Django 5 для начинающих

Прогресс по курсу:  9/1004

7.3 Доработки системы авторизации и регистрации, добавление сессий
3 из 4 шагов пройдено
0 из 5 баллов  получено

Доработка формы регистрации

Далее нам нужна форма, которая будет отображаться пользователям, проверять данные и сохранять их в базе данных.

К счастью, нам не нужно изобретать велосипед, потому что в Django есть встроенная простая в использовании форма UserCreationForm. Это форма, которая создает пользователя без каких-либо привилегий с указанным именем пользователя и паролем.

Поэтому мы можем просто расширить встроенную форму модели и добавить дополнительные поля. Я собираюсь добавить адрес электронной почты, имя и фамилию пользователя.


Давайте откроем наш файл forms.py приложения accounts и изменим наш класс SignUpForm, добавив новые поля:

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm


class SignUpForm(UserCreationForm):
    first_name = forms.CharField(max_length=100)
    last_name = forms.CharField(max_length=100)
    username = forms.CharField(max_length=100)
    email = forms.EmailField()
    password1 = forms.CharField(max_length=50, widget=forms.PasswordInput())
    password2 = forms.CharField(max_length=50, widget=forms.PasswordInput())

    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'username', 'email', 'password1', 'password2']

В мета-классе мы можем создать связь между полями нашей модели и различными полями, которые мы хотим иметь в нашей форме.


Давайте перейдем к views.py, он у нас остается без изменений. Здесь я буду использовать представление на основе классов для обработки формы регистрации:

from django.urls import reverse_lazy
from django.views import generic
from .forms import SignUpForm


class SignUpView(generic.CreateView):
    form_class = SignUpForm
    success_url = reverse_lazy("login")
    template_name = "registration/signup.html"

По большому счету мы немного изменили нашу форму, добавив поля и сделав их обязательными.


Давайте внесем изменения в наш шаблон формы registration/signup.html, добавим обработку ошибок:

{% extends "blog/base.html" %}
{% block title %} Sign Up {% endblock %}
{% block content %}
    <h2> Sign Up </h2>
    {% if form.errors %}
        <div style="display: table; margin: 0 auto; text-align: left;">
            {% for key, value in form.errors.items %}
                <strong>{{ value }}</strong>
            {% endfor %}
        </div>
    {% endif %}
    <form method="post">
        {% csrf_token %}
        <p>Username: {{ form.username }}</p>
        <p>Email: {{ form.email }}</p>
        <p>First Name: {{ form.first_name }}</p>
        <p>Last Name: {{ form.last_name }}</p>
        <p>Password: {{ form.password1 }}
            {{ form.errors.password2 }}</p>
        <p>Confirm Password: {{ form.password2 }}</p>
        <button type="submit">Sign Up</button>
    </form>
    <a href="{% url 'login' %}">Have an account? Go to Log In</a>
{% endblock %}


Приведенный фрагмент кода между {% if form.errors %} и {% endif %} сначала проверяет наличие ошибки, затем перебирает ошибки и отображает сообщение об ошибке в предупреждении начальной загрузки:


Продолжим доработки в следующем шаге.


  • Комментариев
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

Изменил шаблон, чтобы ошибки выводились только под полями, и убрал дублирование:

{% extends "blog/base.html" %}
{% block title %} Sign Up {% endblock %}
{% block content %}
    <h2> Sign Up </h2>
    <form method="post">
        {% csrf_token %}
        {% for field in form %}
            <p>
            {{ field.label }}: {{ field }}
            {% if field.errors %}
                {{ field.errors }}
            {% endif %}
            </p>
        {% endfor %}
        <button type="submit">Sign Up</button>
    </form>
    <p><a href="/accounts/login/">Have an account? Go to Log In</a></p>
{% endblock %}

Пришлось так же немного поправить \blog\static\css\blog.css, иначе ошибки "уплывали" к следующим полям:

.errorlist {
    color: #cc0033;
    /* float: left; уплывали из-за этого стиля */
    clear: both;
    font-weight: bold;  /* Добавил выделение здесь */
    padding-left: 16px; /* Увеличил с 10 до 16 */
}

Теперь выглядит так:

Изменен ilya kutaev

В приведенном шаблоне содержится неточность, из-за которой при несовпадении  паролей этот код не отрабатывает:

Такого поля (password) на форме нет, есть password1 и password2, и ошибка при несовпадении паролей выводится именно с ключом password2. Нужно исправить на {{ form.errors.password2 }}

@ilya_kutaev, Согласен, поправил.

на фото ссылка accounts/register, а должна же быть accounts/signup вроде как

@Dima_T, спасибо, исправил.

Почему здесь пишется href="/accounts/login/", а не href="{% url "login" %}?

@Александр_Ёлшин, видимо проглядели, и жестко задали адрес, по имени маршрута всегда предпочтительнее, если вдруг будет необходимость изменить адрес страницы, то все ссылки останутся рабочими. Исправил, спасибо что указали на это.

Я, конечно, не душнила, но у нас везде фигурирует фраза "Log In", а юзеру предлагаем "Sign In", если уже есть аккаунт. Да это синонимы, но все же))

@Константин_Малыхин, Спасибо, код поправили, новые скрины сделаем чуть позже.

Почему-то у меня ошибки вообще не хотят высвечиваться в начале страницы, они выскакивают только возле поля 

@Никита_Айзиков, браузер не даёт отправить не корректные данные, но проверять нам нужно всё равно. На браузер нельзя надеятся, так как в одном может быть проверка, а в другом нет. Если интересно, мы можем отключить валидацию на стороне клиента добавив в форму:

<form method="post" novalidate>

в прошлом уроке в `fields` класса Meta был кортеж, в этом список. Это имеет какое-то практическое значение, или там может быть любая коллекция?

@Игорь_Федоренко, Там может быть только список или кортеж. Поправили в прошлом разделе, чтобы не вводить в заблуждение.