How to Create Custom User Model in Django?

Django

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.

Leave a Reply

Your email address will not be published. Required fields are marked *