Расширение модели User
При работе с учетными записями пользователей вы узнаете, что модель User механизма аутентификации с помощью Джанго подходит для распространенных случаев. Однако модель User поставляется с довольно базовыми возможностями. Пользователь может расширить модель User, включив в нее дополнительные данные. Лучшим способом для этого является создание модели профиля, которая содержит все дополнительные поля и связь «один к одному» с моделью User.
Откройте файл models.py приложения account и внесите в него следующий код:
from django.db import models
from django.conf import settings
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
date_of_birth = models.DateField(blank=True, null=True)
photo = models.ImageField(upload_to='users/%Y/%m/%d', blank=True)
def __str__(self):
return 'Profile for user {}'.format(self.user.username)
In order to keep your code generic, use the get_user_model() method to retrieve the user model and the AUTH_USER_MODEL setting to refer to it when defining model's relations to the user model, instead of referring to the auth User model directly.
Связь «один к одному» позволяет связывать профили с пользователями. Поле photo является полем ImageField . Вам потребуется установить один из пакетов Python для управления изображениями. Установите Pillow, запустив в терминале следующую команду:
pip install Pillow==2.9.0
Для обслуживания файлов мультимедиа, загруженных пользователями с сервероа разработки, добавьте следующие параметры в файл settings.py проекта:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL — это базовый URL-адрес для обслуживания файлов мультимедиа, отправляемых пользователями, а MEDIA_ROOT — локальный путь, в котором они находятся. Мы динамически строим путь относительно нашего пути проекта, чтобы сделать код более универсальным.
Отредактируйте основной файл urls.py проекта bookmarks и добавьте в него следующий код:
from django.conf.urls import include, url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^account/', include('account.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Таким образом, сервер разработки Джанго будет отвечать за службу мультимедийных файлов во время разработки.
Вспомогательная функция static() подходит для разработки, но не для использования в продакшн версии.Никогда не обслуживайте статические файлы с Джанго в продакшн версии.
Откройте оболочку и выполните следующую команду, чтобы создать миграцию базы данных для новой модели:
python manage.py makemigrations
Вы увидите следующее:
Migrations for 'account':
0001_initial.py:
- Create model Profile
Затем синхронизируйте базу данных следующей командой:
python manage.py migrate
Вы увидите следующее:
Applying account.0001_initial... OK
Измените файл admin.py приложения account и зарегистрируйте модель Profile на сайте администрирования:
from django.contrib import admin
from .models import Profile
class ProfileAdmin(admin.ModelAdmin):
list_display = ['user', 'date_of_birth', 'photo']
admin.site.register(Profile, ProfileAdmin)
Запустите сервер разработки снова с помощью команды python manage.py runserver
. Теперь вы можете видеть модель Profile в административной части сайта вашего проекта:
Теперь мы позволим пользователям редактировать свой профиль на веб-сайте. Добавьте следующие модели формы в файл forms.py приложения account:
from .models import Profile
class UserEditForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('date_of_birth', 'photo')
Немного о коде выше:
- UserEditForm : Позволит пользователям изменять свое имя, фамилию и электронную почту, хранящиеся во встроенной пользовательской модели.
- ProfileEditForm : Позволит пользователям редактировать дополнительные данные, сохраняемые в пользовательской модели Profile. Пользователи смогут изменить дату рождения и отправить фотографию для своего профиля.
Отредактируйте файл views.py приложения account и сделайте импорт модели Profile:
from .models import Profile
И добавьте следующие строки в представление register под new_user.save():
# Create the user profile
profile = Profile.objects.create(user=new_user)
Когда пользователи регистрируются на нашем сайте, мы создаем пустой профиль, связанный с ними. Необходимо создать объект Profile вручную с помощью административной части сайта для созданных ранее пользователей.
Теперь мы позволим пользователям редактировать их профиль. Добавьте следующий код в тот же файл:
from .forms import LoginForm, UserRegistrationForm, UserEditForm, ProfileEditForm
@login_required
def edit(request):
if request.method == 'POST':
user_form = UserEditForm(instance=request.user, data=request.POST)
profile_form = ProfileEditForm(instance=request.user.profile, data=request.POST, files=request.FILES)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
else:
user_form = UserEditForm(instance=request.user)
profile_form = ProfileEditForm(instance=request.user.profile)
return render(request,
'account/edit.html',
{'user_form': user_form,
'profile_form': profile_form})
Мы используем декоратор login_required, так как пользователи должны авторизоваться для редактирования своего профиля. В этом случае используются две модели форм: UserEditForm для хранения данных встроенной модели User и ProfileEditForm для хранения дополнительных данных профиля. Чтобы проверить представленные данные, мы проверяем, что метод is_valid() обеих форм возвращает значение true. В этом случае мы сохраняем обе формы для обновления соответствующего объекта в базе данных.
Добавьте новый URL шаблон в файл urls.py приложения account:
url(r'^edit/$', views.edit, name='edit'),
Наконец, создайте шаблон для этого представления в templates/account/ и назовите его edit.html. Добавьте в него следующий код:
{% extends "base.html" %}
{% block title %}Edit your account{% endblock %}
{% block content %}
<h1>Edit your account</h1>
<p>You can edit your account using the following form:</p>
<form action="." method="post" enctype="multipart/form-data">
{{ user_form.as_p }}
{{ profile_form.as_p }}
{% csrf_token %}
<p><input type="submit" value="Save changes"></p>
</form>
{% endblock %}
We include enctype="multipart/form-data" in our form to enable file uploads. We use one HTML form to submit both the user_form and the profile_form forms.
Зарегистрируйте нового пользователя и пройдите по адресу http://127.0.0.1:8000/account/edit/ . Вы увидите следующую страницу:
Теперь можно также отредактировать страницу панели мониторинга и включить ссылки для редактирования страниц профиля и смены пароля. Откройте шаблон account/dashboard.html и замените эту строку:
<p>Welcome to your dashboard.</p>
...на эту:
<p>Welcome to your dashboard. You can <a href="{% url "edit" %}">edit your profile</a> or <a href="{% url "password_change" %}">change your password</a>.</p>
Теперь пользователи могут получить доступ к форме для редактирования профиля в панели управления.