Extending or Replacing the Default User Model in Django
Django provides a built-in User
model for authentication and user management. However, you may need to customize it to add extra fields or functionality. This article covers how to extend or replace the default user model in Django with examples.
1. Why Extend or Replace the User Model?
The default Django User
model includes fields like username, email, and password. If you need additional fields (e.g., date of birth, profile picture) or wish to remove unused fields, you can either extend or replace the model.
2. Extending the Default User Model
You can extend the default user model using a One-to-One relationship. This approach allows you to add extra fields without modifying the existing model.
Example: Extending with a Profile Model
# models.py
from django.contrib.auth.models import User
from django.db import models
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
date_of_birth = models.DateField(null=True, blank=True)
profile_picture = models.ImageField(upload_to='profiles/', null=True, blank=True)
def __str__(self):
return self.user.username
Connect the Profile
model to the User
model using Django signals:
# signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from .models import Profile
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
Don't forget to register the signals:
# apps.py
from django.apps import AppConfig
class MyAppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'myapp'
def ready(self):
import myapp.signals
3. Replacing the Default User Model
Replacing the default user model is a more flexible approach but requires careful planning because it must be done at the start of the project.
Steps to Replace the Default User Model
Define a custom user model by subclassing AbstractUser
or AbstractBaseUser
.
Example: Using AbstractUser
# models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
date_of_birth = models.DateField(null=True, blank=True)
profile_picture = models.ImageField(upload_to='profiles/', null=True, blank=True)
Update settings.py
Set the AUTH_USER_MODEL
to point to your custom user model:
# settings.py
AUTH_USER_MODEL = 'myapp.CustomUser'
Migrate Changes
Run migrations to apply the changes:
python manage.py makemigrations
python manage.py migrate
Example: Using AbstractBaseUser
For full control over the user model, subclass AbstractBaseUser
and implement your own fields and methods:
# models.py
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models
class CustomUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError("The Email field is required")
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):
email = models.EmailField(unique=True)
date_of_birth = models.DateField(null=True, blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = CustomUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
Update Admin Interface
Customize the admin interface for the custom user model:
# admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import CustomUser
class CustomUserAdmin(UserAdmin):
model = CustomUser
fieldsets = UserAdmin.fieldsets + (
(None, {'fields': ('date_of_birth',)}),
)
admin.site.register(CustomUser, CustomUserAdmin)
4. Choosing the Right Approach
Use the Profile Model approach for simple extensions and Custom User Model if you need full customization.
5. Conclusion
Extending or replacing the default user model in Django allows you to customize user management according to your application's requirements. Plan your approach carefully, especially when replacing the user model, as it affects the entire project.