In views.py
I've got a method called 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 print gives me all the fields a user entered:
request <QueryDict: {'csrfmiddlewaretoken': ['***'], 'username': ['12312312gdsgdsg'], 'email': ['[email protected]'], 'password1': ['123fhfhfh'], 'password2': ['989898gdfjgndf']}>
When I call form.is_valid() it gets to clean data of my form of 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')
The form's cleaned data print returns me the same dictionary as the post, but WITHOUT password2
:
cleaned data {'username': '12312312gdsgdsg', 'email': '[email protected]', 'password1': '123fhfhfh'}
I'm new to Django and I don't understand why password2 cannot get to be in cleaned data. I have already watched the post about data validation (Django Forms cleaned_data missing certain fields), but the person of this problem made a wrong field and his data couldn't be validated. I've got 2 identical fields for passwords, password1 gets to be cleaned and password2 does not. I cannot understand the problem.
My signup.html
template:
{% extends 'base.html' %}
{% load static %}
{% block head %}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/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 %}
Many thanks for your help!
CodePudding user response:
Django's UserCreationForm
[Django-doc] implements a clean_password2
that will check if the two passwords match, and raise an exception otherwise.
You can customize the error message with:
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
Here the 'some text to translate'
should be the text you want to use when the two passwords do not match.