Creating the Custom User Model
Learn how to create a custom user model in Django.
We'll cover the following
Model creation
We’ll create a custom model for the users along with the custom model manager for the user
model in models.py
. Then we’ll use settings.py
to tell Django to use our custom user
model instead of the default one.
The difference between the default Django model and a custom model is that the default model is not flexible, while the custom model is. The primary attributes of a default user model are username
, password
, email
, first_name
, and last_name
. But with a custom user model, we can either eliminate some of these fields, such as the last name, and add new ones, such as a date of birth, or change their behavior, such as making the email field unique.
Custom user manager
In Django, if we create a custom user model, we also have to create a custom user model manager. Since we are using AbstractBaseUser
, we’ll inherit the BaseUserManager
class with two additional methods: create_user()
and create_superuser()
. Both methods are required.
from django.db import modelsfrom django.contrib.auth.models import (BaseUserManager, AbstractBaseUser, PermissionsMixin)from rest_framework_simplejwt.tokens import RefreshTokenclass UserManager(BaseUserManager):def create_user(self, email, password, **extra_fields):"""Use email, password, and the additional fields to create and save user objects."""if not email:raise TypeError('User must have an email')user = self.model(email=self.normalize_email(email), **extra_fields)user.set_password(password)user.save()return userdef create_superuser(self, email, password, **extra_fields):"""Use email, password, and the additional fields to create and save superuser objects."""user = self.create_user(email, password, **extra_fields)user.is_superuser = Trueuser.is_active = Trueuser.is_verified = Trueuser.is_staff = Trueuser.save()return user
Custom user model
We can create a custom user model by either subclassing AbstractUser
or AbstractBaseUser
. The first option, class User(AbstractUser, PermissionsMixin)
, works if we only want to remove the username field from the default user model. The second option, class User(AbstractBaseUser, PermissionsMixin)
is a better choice if we are creating our user model from scratch. In this case, we’ll use AbstractBaseUser
so we can look at how to build a user model from scratch.
# ... UserManager classclass User(AbstractBaseUser, PermissionsMixin):email = models.EmailField(max_length=255, unique=True, db_index=True)is_verified = models.BooleanField(default=False)is_active = models.BooleanField(default=False)is_staff = models.BooleanField(default=False)created_at = models.DateTimeField(auto_now_add=True)USERNAME_FIELD = 'email'objects = UserManager()def __str__(self):return self.emaildef get_tokens(self):refresh = RefreshToken.for_user(self)return {'refresh': str(refresh),'access': str(refresh.access_token)}
In the code above, the user model above has five attributes.
User Model Attributes
Attributes | Descriptions |
|
|
|
|
|
|
|
|
|
|
Aside from those attributes, we have:
- The
USERNAME_FIELD = 'email'
, which sets email as the unique identifier of the user model. - The
__str__()
method, which represents objects of a class as a given string. In our case, it returns the user as an email address. - The
objects = UserManager()
, which tells Django where to get the objects of the class, such asUserManager()
. - The
get_tokens()
method, which lets us manually create Simple JWTs for users.
Settings
We have to tell Django to use our custom user model, which is in the main
app. Let’s add this line of code at the bottom of the settings.py
file:
AUTH_USER_MODEL = 'main.User'
Try it yourself
Let’s try applying what we’ve learned in the code widget below:
- Add the required imports at the top of the
models.py
file. - Create the custom user model manager by extending the
BaseUserManager
class inmodels.py
. - Create the custom user model by extending the
AbstractBaseUser
class inmodels.py
. - Tell Django to use the custom user model
User
as the user model insettings.py
.
If we do everything right in the playground above, we should see the default Django landing page saying: “The install worked successfully! Congratulations!”
If the server stops, we have to rerun it using the python3 manage.py runserver 0.0.0.0:8000
command in the playground’s terminal.