Summary: In this tutorial, you will learn to create a custom user model by extending the predefined AbstractBaseUser and BaseUserManager classes in Django.
What is user Model in Django?
In Django, a user model is a model that represents a user of the application. It is used to handle user authentication and authorization.
The built-in user model in Django is the django.contrib.auth.models.User
model, which includes fields such as username, password, email, and first and last name.
Here is an example of how you can use it in your Django app:
from django.contrib.auth.models import User
# Create a new user
user = User.objects.create_user(
username='johndoe',
email='johndoe@example.com',
password='password123'
)
# Save the user to the database
user.save()
# Update an existing user
user.first_name = 'John'
user.last_name = 'Doe'
user.save()
# Retrieve a user
user = User.objects.get(username='johndoe')
# Delete a user
user.delete()
You can also use the built-in User
model to authenticate users, check their permissions, and perform other tasks related to user management.
from django.contrib.auth import authenticate
# Authenticate a user
user = authenticate(username='johndoe', password='password123')
if user is not None:
print("User is authenticated")
else:
print("Invalid username/password")
What are AbstractBaseUser and BaseUserManager?
AbstractBaseUser
and BaseUserManager
are two classes provided by Django to help developers create custom user models.
AbstractBaseUser
is an abstract base class that provides the basic structure for creating a custom user model. It contains fields and methods that are commonly used in user models, such as username
, password
, email
, is_active
, and is_staff
. It also provides methods for checking permissions and authentication. Developers can subclass AbstractBaseUser
and add or override fields and methods as necessary.
BaseUserManager
is a class that provides the basic structure for creating a custom user manager. User managers are used to handle the creation and management of user objects, such as creating new users, saving user data, and checking for the existence of a user. BaseUserManager
provides methods for creating and saving users, such as create_user()
and create_superuser()
. Developers can subclass BaseUserManager
and add or override methods as necessary.
By subclassing AbstractBaseUser
and BaseUserManager
you can create your custom user model and user manager respectively. These classes are not required to use but they provide a convenient starting point for creating custom user models and managers.
Example: Create a custom user model in Django
Here’s an example of how you might create a custom user model in Django:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class MyUserManager(BaseUserManager):
def create_user(self, email, password=None):
"""
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password):
"""
Creates and saves a superuser with the given email and password.
"""
user = self.create_user(
email,
password=password,
)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
@property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
In this example, we created a custom user model called MyUser
that subclasses AbstractBaseUser
, which is one of the base classes provided by Django for creating custom user models.
The MyUser
model has an email field, which is used as the primary key and also as the unique identifier for authentication and authorization.
The MyUserManager
class is used as the manager for the custom user model and it contains methods for creating and saving users.
We can then use MyUser
model for authentication and authorization instead of the built-in User
model provided by Django.
For this, you need to set the custom user model in the AUTH_USER_MODEL
setting in your Django settings file.
AUTH_USER_MODEL = 'path.to.MyUser'
This is just a basic example, you can add or remove fields and methods of your choice as per your requirement.
Why I did not subclass django.contrib.auth.models.User?
In the example I provided, I did not subclass django.contrib.auth.models.User
because that would have meant inheriting all the fields and methods of the built-in User model, and using them in the custom user model.
Instead, I used AbstractBaseUser
to subclass it and created a custom user model from scratch. This allows for greater flexibility in terms of the fields and methods that are included in the custom user model. It also allows for a more fine-grained control over how the user model behaves and how it interacts with the rest of the application.
Another reason to use AbstractBaseUser
is that it does not include any fields or methods that are not essential for a user model, making it more minimal. By using AbstractBaseUser
, I can define only the fields and methods that are relevant to the specific use case, rather than inheriting fields and methods that may not be needed.
Additionally, it’s a good practice to use AbstractBaseUser
if you want to use a different database field as the primary key of the user model.
In the example I provided, the email field is used as the primary key and also as the unique identifier for authentication and authorization, this is not the default behavior of User
model which uses the username
field as the primary key and unique identifier.