Contents

Django Custom Usermodel

Learning Django Series: 1


Django ships with a built-in User model for authentication and it is good enough for most common cases. However, according to Django docs, the best practice is always use a custom user model for all new django projects.

Why to use cutom user model

  • Convenience: django default Usermodel uses username as identifier to login. A custom user model makes logging with email possible thus improves user experience a little bit better.
  • Future change: even 90% of time you may not need to customize User, but it is good to have this option there to avoid the burden of migrations.
  • Performance: you can create a sperate Profile model and join to the User model if you don’t have a custom user model, that apprently performs less efficient.

How to implement custom user model

Custom user model was added in django 1.5. Up until that version the recommended approach was to add a OneToOneField(also known as extending the existing user model or Profile model) to User.

Substituting a custom user model is the standard and less hassle way after django 1.5. There are two options to create a custom user model: extend AbstractUser or AbstractBaseUser.

  1. extend AbstractUser: keeps the default User fields and permissions.
  2. extend AbstractBaseUser: start from scratch to create a new User model.

Creating a custom user model when staring a project requires 5 steps:

  1. Create a new app name myapp and add it to INSTALLED_APPS in settings.py
  2. Create a MyUser model
  3. Update config/settings.py
  4. Customize UserCreationForm and UserChangeForm
  5. Register the model in the app’s admin.py
    Note
    All those steps should be done BEFORE first migration!

Create new user model:

1
2
3
4
5
# myapp/models.py
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass

Set reference to custom user model

Django provides AUTH_USER_MODEL setting to override built-in User model.

1
2
# config/settings.py
AUTH_USER_MODEL = 'myapp.MyUser'

Customize user forms

A user model can bot created and edited within the django admin. So we need to subclass UserCreationForm and UserChangeForm to user our new MyUser model.

get_user_model method will look to AUTH_USER_MODEL config in settings.py.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# myapp/forms.py
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm, UserChangeForm

class MyUserCreationForm(UserCreationForm):
    class Meta:
        model = get_user_model()
        fields = ('email', 'username',)
         
class MyUserChangeForm(UserChangeForm):
    class Meta:
        model = get_user_model()
        fields = ('email', 'username',)
Note
The password field is implicitly included by default.

Customize user admin

Finally we come to the end of journey: update admin.py. We need to extend the existing django UserAdmin and let register our new user model and new user admin to django admin.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# myapp/admin.py
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from .forms import MyUserCreationForm, MyUserChangeForm

MyUser = get_user_model()

class MyUserAdmin(UserAdmin):
    add_form = MyUserCreationForm
    form = MyUserChangeForm
    model = MyUser
    list_display = ['email', 'username']

admin.site.register(MyUser, MyUserAdmin)

Conclusion

Now we replaced django’s default user model with our own custom user model. It is a basic user model with similar functionality with default one, but we can conveniently add new fields to it without sweat to deal with database migrations in the middle of projects.

Check out following resources for further cusomizing:

  1. https://testdriven.io/blog/django-custom-user-model/
  2. https://learndjango.com/tutorials/django-custom-user-model