0
0
DjangoHow-ToBeginner · 4 min read

How to Create a Custom User Model in Django

To create a custom user model in Django, subclass AbstractBaseUser and PermissionsMixin, then define a custom user manager by subclassing BaseUserManager. Update AUTH_USER_MODEL in settings.py to point to your new model.
📐

Syntax

Creating a custom user model involves two main parts:

  • User model: Subclass AbstractBaseUser and PermissionsMixin to define user fields and authentication behavior.
  • User manager: Subclass BaseUserManager to handle user creation methods like create_user and create_superuser.
  • Set USERNAME_FIELD to specify the unique identifier for login.
  • Update AUTH_USER_MODEL in settings.py to your custom model.
python
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.db import models

class CustomUserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('Email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        return self.create_user(email, password, **extra_fields)

class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=30, blank=True)
    last_name = models.CharField(max_length=30, blank=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []
💻

Example

This example shows a complete custom user model using email as the login field, with a custom manager to create users and superusers. It also includes the necessary settings.py update.

python
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.db import models

class CustomUserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('Email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')
        return self.create_user(email, password, **extra_fields)

class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=30, blank=True)
    last_name = models.CharField(max_length=30, blank=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

# settings.py snippet
AUTH_USER_MODEL = 'yourapp.CustomUser'
Output
No direct output; defines a custom user model and manager for Django authentication.
⚠️

Common Pitfalls

Common mistakes when creating a custom user model include:

  • Not setting AUTH_USER_MODEL in settings.py, which causes Django to use the default user model.
  • Forgetting to implement a custom user manager with create_user and create_superuser methods.
  • Using username field instead of a unique identifier like email without adjusting USERNAME_FIELD.
  • Changing the user model after migrations have been applied, which can cause database conflicts.

Always create the custom user model before the first migration.

python
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models

# Wrong: No custom manager
class BadUser(AbstractBaseUser):
    email = models.EmailField(unique=True)
    USERNAME_FIELD = 'email'

# Right: Custom manager included
class GoodUserManager(BaseUserManager):
    def create_user(self, email, password=None):
        if not email:
            raise ValueError('Email required')
        email = self.normalize_email(email)
        user = self.model(email=email)
        user.set_password(password)
        user.save(using=self._db)
        return user

class GoodUser(AbstractBaseUser):
    email = models.EmailField(unique=True)
    USERNAME_FIELD = 'email'
    objects = GoodUserManager()
📊

Quick Reference

StepDescription
1Create a custom user manager subclassing BaseUserManager.
2Create a custom user model subclassing AbstractBaseUser and PermissionsMixin.
3Define USERNAME_FIELD and REQUIRED_FIELDS in the user model.
4Set AUTH_USER_MODEL in settings.py to 'yourapp.CustomUser'.
5Create and apply migrations before using the model.

Key Takeaways

Always define a custom user manager with create_user and create_superuser methods.
Set USERNAME_FIELD to the unique login field like email.
Update AUTH_USER_MODEL in settings.py before the first migration.
Do not change the user model after migrations are applied.
Use AbstractBaseUser and PermissionsMixin to build flexible user models.