[Разработка веб-сайтов, Python, Django] Отношение один к одному: связывание модели пользователя с кастомной моделью профиля в Django (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Перевод статьи подготовлен в преддверии старта курса «Web-разработчик на Python».
Пфф… Снова базы данных?
В реляционной базе данных есть три основных отношения:
- Отношение «один-к-одному»;
- Отношение «один-ко-многим»;
- Отношение «многие-ко-многим».
В этой статье мы будем разбираться с первым из них – отношением «один-к-одному».
Обычно в Django уже есть модель пользователя, которая поставляется с фреймворком. Она поставляется со своими полями, методами, атрибутами и т.д. Недостатком этой модели пользователя является то, что она не позволяет добавлять специальные поля отдельно от значений по умолчанию уже представленных в Django. Это может стать серьезной проблемой, поскольку разработчику может понадобиться полностью настроить профиль пользователя/клиента из группы аутентифицированных пользователей. Например, сайту блога может понадобиться профиль автора, который будет включать в себя фотографию пользователя, контактный адрес, хобби, нишу и т.д. А модель пользователя, поставляемая с Django, не позволяет так сделать.
Чтобы решить эту проблему, разработчики создают кастомную модель профиля и соединяют ее с моделью пользователя в Django по умолчанию с помощью отношения «один-к-одному». Так получается, что пользователь гарантированно подключен к одному профилю и наоборот. Кроме того, эта механика позволяет лучше управлять настройкой модели профиля.
Теперь я расскажу вам, как в Django можно сделать такую настройку.
1. Используйте модель пользователя в Django по умолчанию
В том приложении, где вы хотите создать профиль, создайте новый файл forms.py. В forms.py импортируйте следующие модули:
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
Создайте класс, который будет наследоваться от UserCreationForm. Внутри этого класса создайте другой мета-класс, у которого будут две переменные: model и fields. В переменной model будет храниться ваша модель пользователя, а в переменной fields – поля формы, которые будут созданы.
class createUserForm(UserCreationForm):
class meta:
model = User
fields = ['username', 'password1', 'password2']
Код выше создаст форму с полями для имени пользователя, пароля и подтверждения пароля.
2. Создайте свою кастомную модель профиля пользователя.
В файле models.py импортируйте модель пользователя по умолчанию.
from django.contrib.auth.models import User
Дальше нужно создать свою модель профиля, а также создать поле пользователя со связью «один-к-одному» с моделью пользователя по умолчанию в Django.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True,)
name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
address = models.CharField(max_length=200, null=True)
def __str__(self):
return self.name
3. Создайте форму для своей модели профиля.
Откройте файл form.py и импортируйте свою модель профиля из models.py, также добавьте несколько других импортов, которые пригодятся при создании формы профиля.
from django import forms
from django.utils.translation import ugettext_lazy as _
from .models import Profile
Затем создайте класс, который будет наследоваться от forms.ModelForm. В этом классе создайте другой мета-класс, в котором будут две переменные: model и fields. Переменная model содержит модель профиля, а fields – поля формы, которые будут созданы.
class profileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['name', 'email', 'address']
#The labels attribute is optional. It is used to define the labels of the form fields created
labels = {
"name": _("Name "),
"email": _("Email Address"),
"address": _("Street Address"),
}
Теперь, когда формы готовы, мы определим логику views.py перед тем, как рендерить его в наши шаблоны.
4. Пропишите логику в views.py.
Для работы с формами, созданными в forms.py нужно импортировать их в наш views.py, и добавить еще несколько модулей, которые пригодятся для создания логики.
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login,
from django.contrib import messages
from .models import Profile
from .forms import createUserForm, profileForm
Теперь создадим страницу регистрации. Назовем ее просто registerPage. Создадим пустой контекстный словарь и вернем рендер.
def registerPage(request):
context = {}
return render(request, 'app_name/register.html', context)
Присвоим значения из формы переменным, вызвав метод POST. Затем передадим переменные в контекстный словарь.
def registerPage(request):
if request.method == 'POST':
form = createUserForm(request.POST)
profile_form = profileForm(request.POST)
context = {'form': form, 'profile_form': profile_form}
return render(request, 'app_name/register.html', context)
Затем мы сделаем валидацию обеих форм и сохраним их после нее.
def registerPage(request):
if request.method == 'POST':
form = createUserForm(request.POST)
profile_form = profileForm(request.POST)
if form.is_valid() and profile_form.is_valid():
user = form.save()
#we don't save the profile_form here because we have to first get the value of profile_form, assign the user to the OneToOneField created in models before we now save the profile_form.
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
context = {'form': form, 'profile_form': profile_form}
return render(request, 'app_name/register.html', context)
Если значения форм валидированы и сохранены, мы выведем сообщение об успешном выполнении операции и перенаправим пользователя на страницу входа в систему.
def registerPage(request):
if request.method == 'POST':
form = createUserForm(request.POST)
profile_form = profileForm(request.POST)
if form.is_valid() and profile_form.is_valid():
user = form.save()
#we don't save the profile_form here because we have to first get the value of profile_form, assign the user to the OneToOneField created in models before we now save the profile_form.
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
messages.success(request, 'Your account has been successfully created')
return redirect('login')
context = {'form': form, 'profile_form': profile_form}
return render(request, 'app_name/register.html', context)
5. Рендер шаблона
В файле register.html создадим тег формы с помощью метода POST и action со значением пустой строки. В тег формы поместим csrf_token в формате шаблона django, а затем будем динамически визуализировать формы (форму пользователя и профиля). Также не забудем про кнопку отправки.
<form method="POST" action="">
{% csrf_token %}
<h3>Register Profile</h3>
<div class="form-field">
{{profile_form.name.label_tag}}
{{profile_form.name}}
</div>
<div class="form-field">
{{form.username.errors}}
{{form.username.label_tag}}
{{form.username}}
</div>
<div class="form-field">
{{profile_form.email.label_tag}}
{{profile_form.email}}
</div>
<div class="form-field">
{{profile_form.address.label_tag}}
{{profile_form.address}}
</div>
<div class="form-field">
{{form.password1.errors}}
{{form.password1.label_tag}}
{{form.password1}}
</div>
<div class="form-field">
{{form.password2.errors}}
{{form.password2.label_tag}}
{{form.password2}}
</div>
<hr>
<input id="form-button" class="btn btn-success btn-block" type="submit" value="Create Profile">
<br>
{{form.non_field_errors}}
<p>Already have an account? <a href="{% url 'login' %}">Login</a></p>
</form>
Поскольку после заполнения формы, ее проверки и сохранения, мы перенаправляем на страницу входа в систему, сообщение об успешности операции будет отображаться на странице входа в систему снизу прямо перед надписью «Don't have an account? Register».
<form method="POST" action="">
...
<hr>
<input id="form-button" class="btn btn-success btn-block" type="submit" value="Login">
{% for message in messages %}
<p>{{message}}</p>
{% endfor %}
<p>Don't have an account? <a href="{% url 'store:register' %}">Register</a></p>
</form>
Вот так можно создать модель профиля для вашего сайта, связанную с вашей моделью пользователя отношением «один-к-одному».
оригинал
===========
Источник:
habr.com
===========
===========
Автор оригинала: Aduke Adeoye
===========Похожие новости:
- [SQL, Microsoft SQL Server, Администрирование баз данных] Шифрование в MySQL: хранилище ключей (перевод)
- [JavaScript, Программирование, Разработка веб-сайтов] Основные команды bash, git, npm и yarn, а также немного о package.json и semver
- [Laravel, PHP, Разработка веб-сайтов] Laravel–Дайджест (28 сентября – 4 октября 2020)
- [Python] Формат таблиц в pandas
- [Веб-дизайн, Разработка веб-сайтов, Google Web Toolkit, Поисковая оптимизация, Голосовые интерфейсы] Современное SEO: качество страниц
- [Big Data, Интернет вещей, Информационная безопасность] Почему незащищенные потребительские системы интернета вещей теперь представляет собой серьезную бизнес-проблему (перевод)
- [Учебный процесс в IT] Идти в преподаватели или нет? Помогаем побороть страхи, негативный опыт и понять, надо ли вам это
- [Python] Простейший голосовой помощник на Python
- [Управление персоналом, Карьера в IT-индустрии, Тестирование IT-систем] Найм Entry Level/Junior QA: за и против
- [Программирование, Анализ и проектирование систем, Проектирование и рефакторинг, Промышленное программирование] Шаблоны GRASP: Polymorphism, Pure Fabrication, Indirection, Protected Variations
Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_python, #_django, #_python, #_django, #_databases, #_developer, #_blog_kompanii_otus._onlajnobrazovanie (
Блог компании OTUS. Онлайн-образование
), #_razrabotka_vebsajtov (
Разработка веб-сайтов
), #_python, #_django
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:04
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Перевод статьи подготовлен в преддверии старта курса «Web-разработчик на Python». Пфф… Снова базы данных? В реляционной базе данных есть три основных отношения:
В этой статье мы будем разбираться с первым из них – отношением «один-к-одному». Обычно в Django уже есть модель пользователя, которая поставляется с фреймворком. Она поставляется со своими полями, методами, атрибутами и т.д. Недостатком этой модели пользователя является то, что она не позволяет добавлять специальные поля отдельно от значений по умолчанию уже представленных в Django. Это может стать серьезной проблемой, поскольку разработчику может понадобиться полностью настроить профиль пользователя/клиента из группы аутентифицированных пользователей. Например, сайту блога может понадобиться профиль автора, который будет включать в себя фотографию пользователя, контактный адрес, хобби, нишу и т.д. А модель пользователя, поставляемая с Django, не позволяет так сделать. Чтобы решить эту проблему, разработчики создают кастомную модель профиля и соединяют ее с моделью пользователя в Django по умолчанию с помощью отношения «один-к-одному». Так получается, что пользователь гарантированно подключен к одному профилю и наоборот. Кроме того, эта механика позволяет лучше управлять настройкой модели профиля. Теперь я расскажу вам, как в Django можно сделать такую настройку. 1. Используйте модель пользователя в Django по умолчанию В том приложении, где вы хотите создать профиль, создайте новый файл forms.py. В forms.py импортируйте следующие модули: from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User Создайте класс, который будет наследоваться от UserCreationForm. Внутри этого класса создайте другой мета-класс, у которого будут две переменные: model и fields. В переменной model будет храниться ваша модель пользователя, а в переменной fields – поля формы, которые будут созданы. class createUserForm(UserCreationForm):
class meta: model = User fields = ['username', 'password1', 'password2'] Код выше создаст форму с полями для имени пользователя, пароля и подтверждения пароля. 2. Создайте свою кастомную модель профиля пользователя. В файле models.py импортируйте модель пользователя по умолчанию. from django.contrib.auth.models import User
Дальше нужно создать свою модель профиля, а также создать поле пользователя со связью «один-к-одному» с моделью пользователя по умолчанию в Django. class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True,) name = models.CharField(max_length=200, null=True) email = models.CharField(max_length=200, null=True) address = models.CharField(max_length=200, null=True) def __str__(self): return self.name 3. Создайте форму для своей модели профиля. Откройте файл form.py и импортируйте свою модель профиля из models.py, также добавьте несколько других импортов, которые пригодятся при создании формы профиля. from django import forms
from django.utils.translation import ugettext_lazy as _ from .models import Profile Затем создайте класс, который будет наследоваться от forms.ModelForm. В этом классе создайте другой мета-класс, в котором будут две переменные: model и fields. Переменная model содержит модель профиля, а fields – поля формы, которые будут созданы. class profileForm(forms.ModelForm):
class Meta: model = Profile fields = ['name', 'email', 'address'] #The labels attribute is optional. It is used to define the labels of the form fields created labels = { "name": _("Name "), "email": _("Email Address"), "address": _("Street Address"), } Теперь, когда формы готовы, мы определим логику views.py перед тем, как рендерить его в наши шаблоны. 4. Пропишите логику в views.py. Для работы с формами, созданными в forms.py нужно импортировать их в наш views.py, и добавить еще несколько модулей, которые пригодятся для создания логики. from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, from django.contrib import messages from .models import Profile from .forms import createUserForm, profileForm Теперь создадим страницу регистрации. Назовем ее просто registerPage. Создадим пустой контекстный словарь и вернем рендер. def registerPage(request):
context = {} return render(request, 'app_name/register.html', context) Присвоим значения из формы переменным, вызвав метод POST. Затем передадим переменные в контекстный словарь. def registerPage(request):
if request.method == 'POST': form = createUserForm(request.POST) profile_form = profileForm(request.POST) context = {'form': form, 'profile_form': profile_form} return render(request, 'app_name/register.html', context) Затем мы сделаем валидацию обеих форм и сохраним их после нее. def registerPage(request):
if request.method == 'POST': form = createUserForm(request.POST) profile_form = profileForm(request.POST) if form.is_valid() and profile_form.is_valid(): user = form.save() #we don't save the profile_form here because we have to first get the value of profile_form, assign the user to the OneToOneField created in models before we now save the profile_form. profile = profile_form.save(commit=False) profile.user = user profile.save() context = {'form': form, 'profile_form': profile_form} return render(request, 'app_name/register.html', context) Если значения форм валидированы и сохранены, мы выведем сообщение об успешном выполнении операции и перенаправим пользователя на страницу входа в систему. def registerPage(request):
if request.method == 'POST': form = createUserForm(request.POST) profile_form = profileForm(request.POST) if form.is_valid() and profile_form.is_valid(): user = form.save() #we don't save the profile_form here because we have to first get the value of profile_form, assign the user to the OneToOneField created in models before we now save the profile_form. profile = profile_form.save(commit=False) profile.user = user profile.save() messages.success(request, 'Your account has been successfully created') return redirect('login') context = {'form': form, 'profile_form': profile_form} return render(request, 'app_name/register.html', context) 5. Рендер шаблона В файле register.html создадим тег формы с помощью метода POST и action со значением пустой строки. В тег формы поместим csrf_token в формате шаблона django, а затем будем динамически визуализировать формы (форму пользователя и профиля). Также не забудем про кнопку отправки. <form method="POST" action="">
{% csrf_token %} <h3>Register Profile</h3> <div class="form-field"> {{profile_form.name.label_tag}} {{profile_form.name}} </div> <div class="form-field"> {{form.username.errors}} {{form.username.label_tag}} {{form.username}} </div> <div class="form-field"> {{profile_form.email.label_tag}} {{profile_form.email}} </div> <div class="form-field"> {{profile_form.address.label_tag}} {{profile_form.address}} </div> <div class="form-field"> {{form.password1.errors}} {{form.password1.label_tag}} {{form.password1}} </div> <div class="form-field"> {{form.password2.errors}} {{form.password2.label_tag}} {{form.password2}} </div> <hr> <input id="form-button" class="btn btn-success btn-block" type="submit" value="Create Profile"> <br> {{form.non_field_errors}} <p>Already have an account? <a href="{% url 'login' %}">Login</a></p> </form> Поскольку после заполнения формы, ее проверки и сохранения, мы перенаправляем на страницу входа в систему, сообщение об успешности операции будет отображаться на странице входа в систему снизу прямо перед надписью «Don't have an account? Register». <form method="POST" action="">
... <hr> <input id="form-button" class="btn btn-success btn-block" type="submit" value="Login"> {% for message in messages %} <p>{{message}}</p> {% endfor %} <p>Don't have an account? <a href="{% url 'store:register' %}">Register</a></p> </form> Вот так можно создать модель профиля для вашего сайта, связанную с вашей моделью пользователя отношением «один-к-одному». оригинал =========== Источник: habr.com =========== =========== Автор оригинала: Aduke Adeoye ===========Похожие новости:
Блог компании OTUS. Онлайн-образование ), #_razrabotka_vebsajtov ( Разработка веб-сайтов ), #_python, #_django |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:04
Часовой пояс: UTC + 5