Lucio Lucio - 2 months ago 7
Python Question

How to extend the django User model?

I'm trying to implement the

Users
class from
django.contrib.auth.models
like this:

from django.db import models
from django.contrib.auth.models import User


class Registration(models.Model):
'''Represents a user registration.'''
user = models.ForeignKey(User)
registration_date = models.DateTimeField(auto_now_add=True, help_text='The date of the registration')

def __str__(self):
return '%s - %s' % (self.user, self.registration_date,)


This user have two attributes enabled by default: username, password

screenshoot

Reading at the code I can see that there are more attributes, like name and email.

How can I enable those hidden (if this is correct) attributes?

Answer

First, these attributes are not hidden. Assuming you have "django.contrib.auth" and "django.contrib.contenttypes" in your INSTALLED_APPS, then you have access to the User model as it is defined in your link. See here for the documentation on how to use/access it.

However, since you specified extending the User model, I expect you wanted to add some of your own fields to it (even though your example registration_date exists and is accessible via myuser.date_joined).


The older, more stable and more common way of doing this is similar to what you have. The only difference is to use a OneToOneField(User) instead of a ForeignKey(User). This makes the relationship bidirectional and more convenient by forcing one. You do need to make sure and create a Registration object for every User created.

In fact, there is an example of exactly what you want in the docs for the OneToOneField.

from django.db import models
from django.contrib.auth.models import User

class Registration(models.Model):
    user = models.OneToOneField(User)
    registration_date = models.DateTimeField(auto_now_add=True)

>>> user = User.objects.get(pk=1)
>>> registration = Registration.objects.create(user=user)
>>> user.registration.registration_date
# Should give the current time
>>> user.get_full_name()
# Should also have all those *hidden* attributes linked above

As of Django 1.5, you can use your own custom User model fairly easily. The documentation for this feature is here. If you are just adding some extra fields, then you can subclass the User model and add your own fields.

from django.db import models
from django.contrib.auth.models import AbstractUser

class MyUser(AbstractUser):
    # We inherit all those nifty things from AbstractUser
    registration_date = models.DateTimeField(auto_now_add=True)

Then enable it in your settings.py by adding AUTH_USER_MODEL = 'myapp.MyUser'. We now have to access the user model a little differently

>>> from django.contrib.auth import get_user_model()
>>> Users = get_user_model()
>>> user = Users.objects.get(pk=1)
>>> user.registration_date
# Should give the current time
>>> user.get_full_name()
# Should have those 'hidden' attributes

All this is available under extending and substituting the User model in the documentation.