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!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ