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@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?
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
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_superuser(). Developers can subclass
BaseUserManager and add or override methods as necessary.
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.
MyUser model has an email field, which is used as the primary key and also as the unique identifier for authentication and authorization.
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.