Стандартна модель користувача User досить корисна, але іноді нам потрібно налаштовувати її під конкретні вимоги додатка.
Розробники почали задаватися питаннями: "Зачекайте-но, а як додати поле date_of_birth для користувача?", "А можна одразу зберігати номер телефону або картинку профілю?". Вбудована модель User гнучка, але не безмежна. Вона має фіксований набір полів (username, email, first_name, last_name, і т.д.), і якщо нам потрібно щось понад це, то доведеться її налаштувати. Прикладів, коли це потрібно, безліч: соціальні мережі, інтернет-магазини, сайти бронювання і багато іншого.
Django пропонує два підходи: розширення моделі через One-to-One зв'язок та створення кастомної моделі користувача. Давайте розберемо обидва варіанти.
1. Стандартна модель User
Давайте спочатку пригадаємо, що собою являє стандартна модель користувача в Django. Вона вже підключена до нашого проєкту і готова до використання. Ось базові поля цієї моделі:
| Поле | Опис |
|---|---|
| username | Ім'я користувача (обов'язкове) |
| Адреса електронної пошти | |
| 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 унікальним і обов'язковим). Тоді за справу береться кастомізація моделі користувача.
Коли обрати кастомну модель?
- Якщо зміни критичні для всієї системи (наприклад,
emailяк унікальний ідентифікатор користувача). - Якщо проєкт тільки починається (так простіше).
- Якщо ви хочете повний контроль над моделлю користувача.
Покрокова кастомізація
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
Особливості та типові помилки
При розширенні через One-to-One зв'язок часто забувають додати сигнали для створення профілю, що призводить до помилки
Profile matching query does not exist.При створенні кастомної моделі необхідно одразу налаштувати її на етапі початку проєкту. Змінити стандартну модель
Userу вже існуючому проєкті дуже складно (доведеться переносити дані).Не забудьте протестувати міграції! Якщо ви використовуєте кастомну модель, неправильно налаштовані міграції можуть призвести до втрати даних.
Якщо ви використовуєте поле
emailяк ідентифікатор, пам'ятайте, що воно має бути унікальним. Переконайтеся, що у вашому проєкті це коректно налаштовано.
Практичне застосування
- У реальних проєктах, таких як соціальні мережі або інтернет-магазини, розширення користувача дозволяє суттєво спростити роботу з даними профілю.
- На співбесідах можуть попросити пояснити, як працює кастомізація моделі користувача, а також які обмеження є у Django.
- Знання цих інструментів дозволить адаптувати Django під складні сценарії, які вимагає бізнес-логіка.
Основний підхід залежить від ваших задач: якщо зміни мінімальні, використовуйте One-to-One зв'язок, а для серйозних змін — кастомну модель. Тепер у вас є ключові інструменти для налаштування користувача в Django!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ