Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Customize the User model's return field

The default return field of Django's User model is 'username'. However, my application needs it to be 'first_name'. Currently, I just forked Django and made this change to the User model:

def __str__(self):
    return self.first_name

It works fine, but I wonder if there are other SIMPLE ways of doing this without forking Django?

like image 986
Randy Tang Avatar asked Dec 11 '15 00:12

Randy Tang


People also ask

What is custom user model in Django?

The default User model in Django uses a username to uniquely identify a user during authentication. If you'd rather use an email address, you'll need to create a custom User model by either subclassing AbstractUser or AbstractBaseUser .


4 Answers

There is a way to inject a new method on your User class.

from django.contrib.auth.models import User

def get_first_name(self):
    return self.first_name

User.add_to_class("__str__", get_first_name)

You can put this in a common application (preferably inside models.py)

Not very clean, but does the job without overriding the entire User model, if you only need this single change.

like image 67
mariodev Avatar answered Oct 15 '22 16:10

mariodev


I think the best way to do this would be to use a custom user model, then define get_full_name() and/or get_short_name() to return first_name.

like image 41
Travis Avatar answered Oct 15 '22 15:10

Travis


First, create a custom user using django documentation

Once, you have your custom user, go to MyUser Class. Add fields like first_name, last_name or whatever you need.

You will get some thing like this.

class MyUser(AbstractBaseUser):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )
    first_name = models.CharField(max_length=32)
    last_name = models.CharField(max_length=32)
    date_of_birth = models.DateField()
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['date_of_birth']

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def __str__(self):              # __unicode__ on Python 2
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin

Now, Edit __str__ function inside your class to this.

    def __str__(self):              # __unicode__ on Python 2
        return self.first_name

Remember, fields like date_of_birth etc are optional.

like image 26
kartikmaji Avatar answered Oct 15 '22 17:10

kartikmaji


Similar to Randy Tang's answer: you can avoid the issue Ramast mentioned by using a Proxy Model:

class MyUser(User):
    class Meta:
        proxy = True

    def __str__(self):
        return self.first_name

As per the docs:

You can create, delete and update instances of the proxy model and all the data will be saved as if you were using the original (non-proxied) model.

like image 35
pianoJames Avatar answered Oct 15 '22 17:10

pianoJames