Поле данных request.POST не попадает в clean_data формы

В views.py у меня есть метод под названием signup:

def signup(request):
    context = {}
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        print("request", request.POST)
        if form.is_valid():
            user = form.save(commit=False) 
            login(request, user)
            return redirect('index')
        else:
            context['form'] = form
    else:  # GET request
        form = SignUpForm()
        context['form'] = form
    return render(request, 'registration/signup.html', context)

Печать запроса дает мне все поля, введенные пользователем:

request <QueryDict: {'csrfmiddlewaretoken': ['***'], 'username': ['12312312gdsgdsg'], 'email': ['123123fsdfesgf@gmail.com'], 'password1': ['123fhfhfh'], 'password2': ['989898gdfjgndf']}>

Когда я вызываю form.is_valid(), она получает чистые данные моей формы forms.py:

class SignUpForm(UserCreationForm):
    username = forms.CharField(
        label="username",
        max_length=30,
        required=True,
        widget=forms.TextInput(
            attrs={
                'type': 'text',
                'placeholder': 'Username',
            }
        ),
    )

    email = forms.EmailField(
        label="email",
        max_length=60,
        required=True,
        widget=forms.TextInput(
            attrs={
                'type': 'text',
                'placeholder': 'Email',
            }
        ),
    )

    password1 = forms.CharField(
        label="password1",
        required=True,
        widget=forms.PasswordInput(
            attrs={
                'type': 'password',
                'placeholder': 'Password',
            }
        ),
    )

    password2 = forms.CharField(
        label="password2",
        required=True,
        widget=forms.PasswordInput(
            attrs={
                'type': 'password',
                'placeholder': 'Confirm Password',
            }
        ),
    )

    def clean(self):
        cleaned_data = super(SignUpForm, self).clean()
        print("cleaned data", cleaned_data)
        password = cleaned_data["password1"]
        confirm_password = cleaned_data["password2"]
        if password != confirm_password:
            self.add_error('confirm_password', "Password and confirm password do not match")
        return cleaned_data

    class Meta:
        model = ServiceUser
        fields = ('username', 'email', 'password1', 'password2')

Печать очищенных данных формы возвращает мне тот же словарь, что и в посте, но БЕЗ password2:

cleaned data {'username': '12312312gdsgdsg', 'email': '123123fsdfesgf@gmail.com', 'password1': '123fhfhfh'}

Я новичок в Django и не понимаю, почему password2 не может попасть в очищенные данные. Я уже смотрел пост о валидации данных (Django Forms cleaned_data missing certain fields), но человек в этой проблеме сделал неправильное поле и его данные не могут быть проверены. У меня есть 2 одинаковых поля для паролей, пароль1 очищается, а пароль2 - нет. Я не могу понять суть проблемы. Мой шаблон signup.html:

{% extends 'base.html' %}
{% load static %}
{% block head %}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="{% static 'css/sign_template.css' %}">
<title>Signup</title>
{% endblock %}
{% block content %}
{% if user.is_authenticated %}
  <meta http-equiv="refresh" content="0; URL={% url 'index' %}" />
{% else %}
<form method="post">
  <div class="sign-card">
    <h3>Signup</h3>
    {% csrf_token %}
    {{ form.errors }}
    {{ form.non_field_errors }}
    <div class="input-div">
      <label for="{{ form.username.id_for_label }}">Username:</label>
      {{ form.username }}
    </div>
    <div class="input-div">
      <label for="{{ form.email.id_for_label }}">Email:</label>
      {{ form.email }}
    </div>
    <div class="input-div">
      <label for="{{ form.password.id_for_label }}">Password:</label>
      {{ form.password1 }}
    </div>
    <div class="input-div">
      <label for="{{ form.password.id_for_label }}">Confirm Password:</label>
      {{ form.password2 }}
    </div>
    {% if form.errors %}
       {% for field in form %}
           {% for error in field.errors %}
              <div class="alert alert-danger alert-dismissible fade show" role="alert">
                  <strong>{{ error|escape }}</strong>
                  <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
              </div>
           {% endfor %}
       {% endfor %}
    {% endif %}

    <button type="submit" class="btn-custom">Sign up</button>
    <p>Already have account? <a href="{% url 'login' %}">Log In</a></p>
  </div>
</form>
{% endif %}
{% endblock %}

Большое спасибо за помощь!

В UserCreationForm [Django-doc] реализована clean_password2, которая будет проверять, совпадают ли два пароля, и вызывать исключение в противном случае.

Вы можете настроить сообщение об ошибке с помощью:

from django.utils.translation import gettext_lazy as _

class SignUpForm(UserCreationForm):
    error_messages = {
        'password_mismatch': _('some text to translate')
    }
    # ⋮
    # do not override the clean method

Здесь 'some text to translate' должен быть текст, который вы хотите использовать, когда два пароля не совпадают.

Вернуться на верх