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
AbstractBaseUserandPermissionsMixinto define user fields and authentication behavior. - User manager: Subclass
BaseUserManagerto handle user creation methods likecreate_userandcreate_superuser. - Set
USERNAME_FIELDto specify the unique identifier for login. - Update
AUTH_USER_MODELinsettings.pyto 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_MODELinsettings.py, which causes Django to use the default user model. - Forgetting to implement a custom user manager with
create_userandcreate_superusermethods. - Using
usernamefield instead of a unique identifier likeemailwithout adjustingUSERNAME_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
| Step | Description |
|---|---|
| 1 | Create a custom user manager subclassing BaseUserManager. |
| 2 | Create a custom user model subclassing AbstractBaseUser and PermissionsMixin. |
| 3 | Define USERNAME_FIELD and REQUIRED_FIELDS in the user model. |
| 4 | Set AUTH_USER_MODEL in settings.py to 'yourapp.CustomUser'. |
| 5 | Create 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.