Extending the User model in Django
Django brings a built-in user authentication system, it includes an User model which has the most common attributes. But in most applications you may need to store additional attributes to users. Django has a way to do this too.
Extending using foreign key
Basically you create your UserProfile
model with a OneToOneField
to User
:
and define in on settings.py
From now on your User
objects will have a get_profile()
method.
I personally can’t see a reason to use this setting (and I hate “getters” methods), you just need to do this:
See the related_name='profile'
parameter, now you don’t need the get_profile()
method anymore, just use user_instance.profile
.
But there is a small problem here, if the user instance don’t have a profile related to it you will receive an ObjectDoesNotExist
exception. This happens with get_profile()
too. And it’s not good to handle the exception every time you access the profile. The simplest way to solve this is connect to django.db.models.signals.post_save
on the User
model and create your UserProfile
instance related to it
Why subclassing User is a bad idea
There are a few reasons I prefer to create user profiles as another model instead of just subclassing the default User. If you think for a while, an user has a lot to do in your site, and there are at a few default steps:
- first she needs to register, confirm by email, and so on
- login and logout, change and reset password
- admins may need to manage groups and permissions, to restrict user actions, offer features to specific groups
- manage profile, with personal information
Django doesn’t handle the first topic, there is a great app to handle registration.
The second and third topics can be done with django.contrib.auth
app, this is exactly it’s purpose.
And then you have the forth topic, which is profiles. As you can see, it can be done as a separate app. A user has a profile. So makes sense to have a profile
attribute in the User object.
If you split features in apps like this it’s easier to reuse too, that’s the idea of django apps after all! The django-registration is an example. And as you can imagine, there are apps to manage profiles too.
Editing User profile in admin
If you’re using admin you may want to edit the UserProfile fields in the same page as the User fields, and it’s possible using admin inlines. Here is how you admin configuration will look like:
Conclusion
As you can see, it quite easy to manage user profiles in django. Although there is a way to hook you profile model in settings.py, you can do it with a simple foreign key. And as usual, there are a few reusable apps around to handle the generic stuff.