Django Custom Usermodel
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
usernameas 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
Profilemodel and join to theUsermodel 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.
- extend
AbstractUser: keeps the defaultUserfields and permissions. - extend
AbstractBaseUser: start from scratch to create a newUsermodel.
Creating a custom user model when staring a project requires 5 steps:
- Create a new app name
myappand add it toINSTALLED_APPSinsettings.py - Create a
MyUsermodel - Update
config/settings.py - Customize
UserCreationFormandUserChangeForm - Register the model in the app's
admin.py
All those steps should be done BEFORE first migration!
Create new user model:
# myapp/models.pyfrom django.contrib.auth.models import AbstractUserclass User(AbstractUser): passSet reference to custom user model
Django provides AUTH_USER_MODEL setting to override built-in User model.
# config/settings.pyAUTH_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.
# myapp/forms.pyfrom django.contrib.auth import get_user_modelfrom django.contrib.auth.forms import UserCreationForm, UserChangeFormclass MyUserCreationForm(UserCreationForm): class Meta: model = get_user_model() fields = ('email', 'username',)class MyUserChangeForm(UserChangeForm): class Meta: model = get_user_model() fields = ('email', 'username',)The
passwordfield 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.
# myapp/admin.pyfrom django.contrib import adminfrom django.contrib.auth import get_user_modelfrom django.contrib.auth.admin import UserAdminfrom .forms import MyUserCreationForm, MyUserChangeFormMyUser = 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: