JavaRush /Курсы /Модуль 3: Django /Настройка модели пользователя в Django

Настройка модели пользователя в Django

Модуль 3: Django
15 уровень , 1 лекция
Открыта

Стандартная модель пользователя User весьма полезна, но иногда нам нужно настраивать её под конкретные требования приложения.

Разработчики начали задаваться вопросами: "Погодите-ка, а как добавить поле date_of_birth для пользователя?", "А можно сразу хранить номер телефона или картинку профиля?". Встроенная модель User гибкая, но не безграничная. Она имеет фиксированный набор полей (username, email, first_name, last_name, и т.д.), и если нам нужно что-то сверх этого, то потребуется её настроить. Примеров, когда это нужно, масса: социальные сети, интернет-магазины, сайты бронирования и многое другое.

Django предлагает два подхода: расширение модели через One-to-One связь и создание кастомной модели пользователя. Давайте разберём оба варианта.

1. Стандартная модель User

Давайте сначала вспомним, что из себя представляет стандартная модель пользователя в Django. Она уже подключена к нашему проекту и готова к использованию. Вот базовые поля этой модели:

Поле Описание
username Имя пользователя (обязательное)
email Адрес электронной почты
first_name Имя
last_name Фамилия
is_staff Может ли пользователь входить в админку
is_active Активен ли пользователь
date_joined Дата регистрации

Вы можете использовать эту модель "из коробки". Например:

from django.contrib.auth.models import User

# Создадим пользователя
user = User.objects.create_user(username='john_doe', email='john@example.com', password='securepassword123')
print(user.username)  # john_doe
print(user.email)     # john@example.com

Но вот проблема: если вы захотите добавить, скажем, поле phone_number, стандартная модель не позволит это сделать. Что же делать? Расширять!

2. Расширение модели через One-to-One связь

Самый простой способ добавить пользовательские данные — создать дополнительную модель, связанную с моделью User через One-to-One связь. Представьте это как расширение стандартной модели, не ломая её. Этот подход удобен, если у вас уже есть проект, активно использующий стандартную модель User, и вы хотите добавить дополнительные поля.

Пример кода

from django.contrib.auth.models import User
from django.db import models

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phone_number = models.CharField(max_length=15, blank=True, null=True)
    date_of_birth = models.DateField(blank=True, null=True)
    avatar = models.ImageField(upload_to='avatars/', blank=True, null=True)

    def __str__(self):
        return f"{self.user.username}'s profile"

Теперь мы можем хранить дополнительные данные в модели Profile!

Зачем делать всё вручную, если можно автоматику? Создадим сигнал, который автоматически создаёт Profile при создании User.

from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User

@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()

Теперь, каждый раз при создании пользователя, будет автоматически создаваться профиль:

user = User.objects.create_user(username='jane_doe', email='jane@example.com', password='supersecurepassword')
print(user.profile)  # <Profile: jane_doe's profile>

И вот мы можем получить доступ к дополнительным данным пользователя:

profile = user.profile
profile.phone_number = "+123456789"
profile.save()

3. Создание кастомной модели пользователя

Иногда One-to-One связь недостаточна. Например, вы хотите полностью заменить стандартную модель или изменить поведение полей (например, сделать поле email уникальным и обязательным). Тогда за дело берётся кастомизация модели пользователя.

Когда выбрать кастомную модель?

  1. Если изменения критичны для всей системы (например, email как уникальный идентификатор пользователя).
  2. Если проект только начинается (так проще).
  3. Если вы хотите полный контроль над моделью пользователя.

Пошаговая кастомизация

1. Создание кастомного пользователя

Создадим свою модель, унаследованную от AbstractBaseUser (или AbstractUser, если хотим использовать стандартные методы и поведение).

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("У пользователя должен быть email")
        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)
    full_name = models.CharField(max_length=150)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['full_name']

    def __str__(self):
        return self.email

2 Регистрация модели в settings.py

После создания кастомной модели нам нужно сообщить Django, что теперь мы используем её:

# settings.py
AUTH_USER_MODEL = 'myapp.CustomUser'

3 Миграция структуры базы данных

После изменений нужно сделать миграции:

python manage.py makemigrations
python manage.py migrate

4. Использование кастомной модели

Теперь ваша кастомная модель полностью интегрирована. Например:

from myapp.models import CustomUser

user = CustomUser.objects.create_user(email='custom@example.com', password='mypassword', full_name='Custom User')
print(user.email)  # custom@example.com

Особенности и типичные ошибки

  1. При расширении через One-to-One связь часто забывают добавить сигналы для создания профиля, что приводит к ошибке Profile matching query does not exist.

  2. При создании кастомной модели необходимо сразу настроить её на этапе начала проекта. Изменить стандартную модель User в уже существующем проекте очень сложно (придётся переносить данные).

  3. Не забудьте протестировать миграции! Если вы используете кастомную модель, неправильно настроенные миграции могут привести к потере данных.

  4. Если вы используете поле email как идентификатор, помните, что оно должно быть уникальным. Убедитесь, что в вашем проекте это корректно настроено.

Практическое применение

  1. В реальных проектах, таких как социальные сети или интернет-магазины, расширение пользователя позволяет существенно упростить работу с данными профиля.
  2. На собеседованиях могут попросить объяснить, как работает кастомизация модели пользователя, а также какие ограничения есть у Django.
  3. Знание этих инструментов позволит адаптировать Django под сложные сценарии, требуемые бизнес-логикой.

Основной подход зависит от ваших задач: если изменения минимальны, используйте One-to-One связь, а для серьёзных изменений — кастомную модель. Теперь у вас есть ключевые инструменты для настройки пользователя в Django!

1
Задача
Модуль 3: Django, 15 уровень, 1 лекция
Недоступна
Создание профиля пользователя
Создание профиля пользователя
1
Задача
Модуль 3: Django, 15 уровень, 1 лекция
Недоступна
Использование кастомной модели пользователя
Использование кастомной модели пользователя
Комментарии (3)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Муса Романюк Уровень 66
11 ноября 2025
Во втором задании не забудьте создать solution.sh и прописать в та нужные команды, без этого у меня не засчитывалась.
Евгений Уровень 82
26 сентября 2025
Валидатор выносит мозг сразу по 2м задачам. Например, во 2ой задаче (Использование кастомной модели пользователя) он в упор не видит мои изменения в settings.py
Дмитрий/MrJonson Уровень 92
14 октября 2025
Тоже самое...