Проблема с формой входа в Django: Форма недействительна, несмотря на правильные учетные данные
Я столкнулся с проблемой, связанной с моей формой входа в Django. Несмотря на предоставление правильных учетных данных, форма постоянно возвращается как недействительная. Вот подробное описание моей установки и проблемы, с которой я столкнулся.
Описание
Я использую AuthenticationForm от Django для обработки входа пользователей. Моя цель - аутентифицировать пользователей и перенаправить их на определенную страницу после успешного входа. Однако проверка формы не проходит, даже если учетные данные верны и пользователь существует в базе данных.
form.py
from django import forms
from .models import UserRegister
from django.contrib.auth.forms import UserCreationForm , AuthenticationForm
from django.core.exceptions import ValidationError
class UserRegisterForm(UserCreationForm):
username = forms.CharField(max_length=50, required=True, widget=forms.TextInput(attrs={'placeholder': 'Username', 'class': 'input-group'}))
email = forms.EmailField(max_length=70, required=True, widget=forms.EmailInput(attrs={'placeholder': 'Email', 'class': 'input-group'}))
password1 = forms.CharField(max_length=128, required=True, widget=forms.PasswordInput(attrs={'placeholder': 'Password', 'class': 'input-group', 'id': 'password'}))
password2 = forms.CharField(max_length=128, required=True, widget=forms.PasswordInput(attrs={'placeholder': 'Confirm Password', 'class': 'input-group', 'id': 'password'}))
class Meta:
model = UserRegister
fields = ['username', 'email', 'password1', 'password2']
error_messages = {
"password_mismatch": "Conform Password Does not match with Password"
}
def clean_email(self):
email = self.cleaned_data.get('email')
if UserRegister.objects.filter(email=email).exists():
raise ValidationError('This email address is already in use.')
return email
def clean_username(self):
username = self.cleaned_data.get('username')
if UserRegister.objects.filter(username=username).exists():
raise ValidationError('This username is already in use.')
return username
def clean_password2(self):
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise ValidationError(self.error_messages['password_mismatch'], code='password_mismatch')
return password2
class UserLoginForm(AuthenticationForm):
username = forms.CharField(max_length=50, required=True ,widget=forms.TextInput(attrs={'placeholder':'Username','class':'input-group'}))
password = forms.CharField(max_length=128,required=True,widget=forms.PasswordInput(attrs={'placeholder':'Password','class':'input-group'}))
views.py
urls.py
from django.urls import path
from . import views
urlpatterns=[path("Home",views.Home),
path("SignUp",views.SignUp,name='Signup'),
path("Products",views.Products,name="Products"),
path('Products/<slug:slug>',views.about_product,name="About Product"),
path("Login",views.Login,name='Log')]
login.html
{% extends "base.html" %}
{% block title %}
Login
{% endblock %}
{% load static %}
{% block css_files %}
<link rel="stylesheet" href="{% static 'reviews/Login.css' %}">
{% endblock %}
{% block content %}
<form method="POST" action="{% url 'Log' %}">
{% csrf_token %}
<div class="input-section">
<div class="input-group">
<label for="{{ form.username.id_for_label }}">Username</label>
{{ form.username }}
{% if form.username.errors %}
<div class="error-message">
{% for error in form.username.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<div class="input-group">
<label for="{{ form.password.id_for_label }}">Password</label>
{{ form.password }}
{% if form.password.errors %}
<div class="error-message">
{% for error in form.password.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<button class="submit-btn" type="submit">Login</button>
</div>
</form>
{% endblock %}
Я полагаю, что у вас две ошибки в Login()
представлении.
Во-первых, вы получаете из формы не тот элемент:
password=form.cleaned_data.get('password')
В форме нет поля с именем password
- в ней есть password1
и password2
.
Из-за этого метод authenticate()
всегда будет возвращать None.
И это ваша вторая ошибка - у вас нет никакой обработки для этого случая:
user = authenticate(
request,
username=form.cleaned_data.get('username'),
password=form.cleaned_data.get('password')
)
if user is not None:
login(request, user)
return HttpResponseRedirect('/Products')
# but what if user is None? ...
Вы обрабатываете только случай, когда вход в систему был успешным, т.е. пользователь не None. Конечно, вы должны вызывать какую-то ошибку, если вход в систему не был успешным?
Я полагаю, что у вас также может быть ошибка в определении формы:
class UserRegisterForm(UserCreationForm):
username = forms.CharField(max_length=50, required=True, widget=forms.TextInput(attrs={'placeholder': 'Username', 'class': 'input-group'}))
email = forms.EmailField(max_length=70, required=True, widget=forms.EmailInput(attrs={'placeholder': 'Email', 'class': 'input-group'}))
password1 = forms.CharField(max_length=128, required=True, widget=forms.PasswordInput(attrs={'placeholder': 'Password', 'class': 'input-group', 'id': 'password'}))
password2 = forms.CharField(max_length=128, required=True, widget=forms.PasswordInput(attrs={'placeholder': 'Confirm Password', 'class': 'input-group', 'id': 'password'}))
Оба виджета PasswordInput
имеют 'id': 'password'
в attrs виджета. Это, конечно, неправильно? Они не могут иметь одинаковый id.