Пользовательские поля модели User
Модель Django по умолчанию User(то есть класс) использует django.contrib.auth.models.User минимальный набор полей данных которые мы рассмотрели в прошлых разделах.
Хотя этих последних полей достаточно для встроенной пользовательской функциональности Django, их может не хватить, если вы ожидаете хранить дополнительные пользовательские данные (например, возраст, телефон, адрес).
Существует два подхода к поддержке дополнительных пользовательских данных: создать отдельную модель для хранения дополнительных данных и создать к ней отношение пользователя (т. е. User с OneToOneField) или переопределить django.contrib.auth.models.User класс по умолчанию для создания пользовательского класса.
В первом подходе метод сохраняет User класс модели Django по умолчанию нетронутым, не требуя дополнительной настройки или усилий по разработке. Именно его мы и попробуем реализовать, для начала необходимо очистить всех пользователей в нашей админ панели, оставив только администратора, чтобы список User был как на скриншоте ниже:
Это необходимо сделать, так как у нас будет конфликт между новыми и старыми пользователями, т.к. у старых пользователей будет отсутствовать ссылка на нужные поля новой модели.
Создание профиля
В этом разделе мы собираемся создать профиль для пользователя, включив дополнительную информацию, такую как изображение профиля и биографию.
Прежде всего, давайте создадим представление профиля внутри accounts/views.py.:
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
@login_required
def profile(request):
return render(request, 'registration/profile.html')
Позже мы изменим это представление, чтобы пользователи могли обновлять свой профиль.
-
Декоратор
login_requiredограничивает доступ для зарегистрированных пользователей. -
Пользователь, не вошедший в систему, не может получить доступ к странице профиля. Если пользователь попытается это сделать,
login_required()он будет перенаправлен наsettings.LOGIN_URL(который мы добавим в файл настройки проекта), передав текущий абсолютный путь в строке запроса.
Пример:/login/?next=/profile/. -
Как видно из примера пути, функция отслеживает, к какой странице пытается получить доступ пользователь. Следовательно, он перенаправит пользователя на страницу профиля, которую он запросил в первую очередь после успешной аутентификации.
Откройте пользовательское приложение accounts и в файл urls.py и добавьте маршрут для просмотра профиля:
from django.urls import path
from .views import SignUpView, CustomLoginView, profile
from django.contrib.auth import views as auth_views
urlpatterns = [
path("signup/", SignUpView.as_view(), name="signup"),
path('login/', CustomLoginView.as_view(redirect_authenticated_user=True, template_name='registration/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(template_name='registration/logout.html'), name='logout'),
path('profile/', profile, name='users-profile'),
]
Создайте шаблон для представления в каталоге шаблонов приложений пользователей - registration/profile.html:
{% extends "blog/base.html" %}
{% block title %}Profile Page{% endblock title %}
{% block content %}
<div>
<h1>This is the profile page for {{user.username}}</h1>
</div>
{% endblock content %}
Мы изменим этот шаблон позже, чтобы отобразить профиль пользователя, но сначала нам нужно сделать пару вещей.
Расширение пользовательской модели с использованием связи «один-к-одному»
Пришло время смоделировать наш профиль, чтобы в базе данных были сохранены изображение профиля пользователя и биографию.
Когда мы хотим сохранить дополнительную информацию о пользователе, не связанную с аутентификацией, мы можем создать новую модель, которая имеет прямую связь с пользователем.
В Django мы можем создавать отношения один к одному между моделями, используя OneToOneField поле модели. Подробнее мы изучали это в разделе 3.4 "Организация связей между таблицами" данного курса.
В отношениях «один-к-одному» одна запись в таблице связана с одной и только одной записью в другой таблице с использованием внешнего ключа. Пример — экземпляр модели пользователя связан с одним и только одним экземпляром профиля.
Хорошо, давайте создадим модель профиля с двумя полями: аватар (изображение профиля) и биографию. Вы можете добавить больше, если хотите.
Добавим в наши модели файла accounts/models.py следующий код:
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
avatar = models.ImageField(default='default.jpg', upload_to='profile_images')
bio = models.TextField()
def __str__(self):
return self.user.username
Первый аргумент OneToOneField указывает, к какой модели будет относиться текущая модель, в нашем случае это модель User.
Второй аргумент on_delete=models.CASCADE означает, что при удалении пользователя удаляется и его/ее профиль.
Далее мы указываем что у пользователя будет свой аватар аргументом ImageField, default='default.jpg' — это изображение по умолчанию, которое пользователь может использовать, если он не загружает его самостоятельно.
Второй аргумент upload_to='profile_images' - это каталог, в который загружаются изображения. bio — это просто текстовое поле, в котором хранится некоторая информация о пользователях.
Django требует от нас установки pillow библиотеки всякий раз, когда мы работаем с ImageField, поэтому перейдите в свой терминал и введите следующее:
pip install pillow==9.2.0
Чтобы изменения вступили в силу внутри нашей базы данных, давайте запустим миграции:
python manage.py makemigrations
python manage.py migrate
Еще один важный шаг — зарегистрировать модель профиля в пользовательском приложении accounts/admin.py:
from accounts.models import Profile
from django.contrib import admin
admin.site.register(Profile)
Приведенный выше код импортирует модель профиля, а затем вызывает admin.site.register ее для регистрации.
Теперь вы можете войти в панель администратора и увидеть созданную нами модель: