Custom Model User

Every new Django project should use the User model of User. The official Django documentation states that this is "strongly recommended", but I'll take it a step further and say without hesitation: you're crazy if you haven't used the user model before.

Why? Because you're going to have to make changes to the user at some point in the life of your project - add a birth date field, age, whatever - and if you didn't start with the User model until the very first migration command you executed, then you're in for a world of hurt.

Once you use a custom model, you can easily add and change it.

Can I switch to a custom model in the middle of a project? Yes. Do you want to do this? It is better not to do it.

There's the easiest way to get every new project started off on the right foot.

Step 1. Create a new project

On the command line, go to a new directory for your projects, use Pipenv to install Django, activate the virtual environment and create a new project named new_project. Let's assume we want to use the code folder in Desktop, so an example on a Mac.

$ cd ~/Desktop
$ mkdir code && cd code
$ pipenv install django
$ pipenv shell
(code) $ django-admin startproject new_project .

Now we need to create the user application and then update the 4 files. Ready?

Step 2: Create a user application

(code) $ python manage.py startapp users

Now let's tell Django about the new application and update AUTH_USER_MODEL so Django knows to use our new CustomUser model instead of the default User model.

Open new_project/settings.py in a text editor and make the following two changes:

# new_project/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Local
    'users.apps.UsersConfig', # новое
]
...
AUTH_USER_MODEL = 'users.CustomUser' # новое

Step 3. CustomUser Model

We want to extend (or copy) the existing User model and call it something else, in our case CustomUser. That's all we need to do. Just make a copy, and then we can customize it the way we like, but still take full advantage of the built-in User.

We don't

even need to add a field at this point!

# users/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    pass
    # add additional fields in here

Step 4: Update Forms

Django uses the User model - now our CustomUser model, since we specified it in AUTH_USER_MODEL everywhere. The two main places are when a new user is created and when we change something from the user. So we have to extend the built-in forms for that again and specify them for our new model CustomUser.

Create a new file users/forms.py and fill it with the following text:

# users/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser

class CustomUserCreationForm(UserCreationForm):

    class Meta(UserCreationForm):
        model = CustomUser
        fields = ('username', 'email')

class CustomUserChangeForm(UserChangeForm):

    class Meta:
        model = CustomUser
        fields = ('username', 'email')

Step 5: Update admin.py

The Django User model is closely related to the excellent built-in admin application admin, so we should tell Django to use CustomUser instead. Here's how:

# users/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 CustomUserCreationForm, CustomUserChangeForm
from .models import CustomUser

class CustomUserAdmin(UserAdmin):
    add_form = CustomUserCreationForm
    form = CustomUserChangeForm
    model = CustomUser
    list_display = ['email', 'username',]

admin.site.register(CustomUser, CustomUserAdmin)

Everything!!!

And that's it. Create a migration file for our changes, and then run the migration for the first time to initialize our database using CustomUser instead of User.

(code) $ python manage.py makemigrations users
(code) $ python manage.py migrate

Congratulations! Your Django project is designed for the future and you can continue working without any problems.

Translation of the article https://wsvincent.com/django-tips-custom-user-model/

Back to Top