from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
"""Extended user model with additional fields."""
email = models.EmailField(unique=True)
phone = models.CharField(max_length=20, blank=True)
avatar = models.ImageField(upload_to='avatars/', null=True, blank=True)
bio = models.TextField(blank=True)
date_of_birth = models.DateField(null=True, blank=True)
email_verified = models.BooleanField(default=False)
# Use email for login
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name']
class Meta:
verbose_name = 'User'
verbose_name_plural = 'Users'
def get_full_name(self):
return f'{self.first_name} {self.last_name}'.strip() or self.username
def __str__(self):
return self.email
# Point to custom user model
AUTH_USER_MODEL = 'accounts.CustomUser'
Extending Django's user model should be done early in projects. I use AbstractBaseUser for full control or AbstractUser to extend the default. Setting AUTH_USER_MODEL points Django to my custom model. I add fields like phone, avatar, or preferences. For profile data, I sometimes use a separate Profile model with OneToOneField. Custom user managers handle creation logic. I ensure username/email uniqueness constraints. Migrations become complex if changing user models mid-project. This provides flexibility for auth requirements.