Ответ
В Django существует четыре основных подхода для кастомизации стандартной модели User, каждый из которых подходит для разных задач.
1. Proxy-модель
Используется, когда нужно изменить поведение модели (например, добавить новые методы или изменить стандартный менеджер), но не требуется добавлять новые поля в базу данных.
- Преимущества: Простота реализации, не требует миграций схемы БД.
- Сценарий: Добавить метод
get_full_name()или кастомный менеджер для фильтрации пользователей.
from django.contrib.auth.models import User
class CustomUserManager(models.Manager):
def get_staff_users(self):
return self.get_queryset().filter(is_staff=True)
class StaffUser(User):
objects = CustomUserManager()
class Meta:
proxy = True
ordering = ('first_name',)
def get_full_name_and_email(self):
return f"{self.first_name} {self.last_name} <{self.email}>"
2. One-to-One связь (Профиль пользователя)
Классический способ добавить дополнительные поля, не затрагивая исходную модель User. Создается отдельная модель (например, Profile), связанная с User отношением «один к одному».
- Преимущества: Не изменяет ядро Django, легко добавлять и удалять поля.
- Сценарий: Хранение аватара, биографии, даты рождения.
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
bio = models.TextField(blank=True)
birth_date = models.DateField(null=True, blank=True)
3. Наследование от AbstractUser
Этот подход позволяет добавить поля непосредственно в таблицу пользователей, унаследовав все поля и методы стандартного User.
- Преимущества: Все данные пользователя хранятся в одной таблице.
- Сценарий: Добавить поле
phone_numberилиpatronymicкак обязательное.
# models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
phone_number = models.CharField(max_length=20, blank=True)
# Добавляем related_name, чтобы избежать конфликтов
groups = models.ManyToManyField('auth.Group', related_name='customuser_set', blank=True)
user_permissions = models.ManyToManyField('auth.Permission', related_name='customuser_set', blank=True)
Важно: После создания такой модели необходимо указать ее в settings.py:
AUTH_USER_MODEL = 'yourapp.CustomUser'
4. Наследование от AbstractBaseUser
Обеспечивает максимальную гибкость. Вы создаете модель пользователя с нуля, определяя только самые базовые поля и методы для аутентификации (например, get_full_name, get_short_name).
- Преимущества: Полный контроль над моделью, включая механизм аутентификации (например, логин по email вместо username).
- Сценарий: Создание системы, где email является основным идентификатором.
# models.py
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class MyUserManager(BaseUserManager):
# ... реализация create_user и create_superuser
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 = []
Также требует регистрации в settings.py через AUTH_USER_MODEL.