Валидация формы, возвращающая False в Django

views.py

def student_login(request):
    form = StudentLoginForm()
    if request.method == 'POST':
        form = StudentLoginForm(data=request.POST)
        print(form.is_valid())
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            print(username)
            user = authenticate(username=username,password=password)
            if user is not None:
                login(request,user)
                return redirect('index')
            else:
                messages.error(request,'Invalid username or password!')
        else:
            messages.error(request,'Invalid username or password!')

    context = {'form':form}
    return render(request,'student_login.html',context)

models.py

class Student(models.Model):
    name = models.CharField(max_length=100)
    username = models.CharField(max_length=100,unique=True,default=None)
    mobile = models.CharField(max_length=8)
    email = models.CharField(max_length=200,unique=True)
    password = models.CharField(max_length=200,default=None,unique=True)
    total_books_due = models.IntegerField(default=0)

    def __str__(self):
        return self.name

forms.py

class StudentLoginForm(forms.ModelForm):
    class Meta:
        model = Student
        fields = ['username','password']
        widgets = {
            'password':forms.PasswordInput(),
        }

student_login.html

{% extends 'base.html' %} 
<!-- {% load crispy_forms_tags %}  -->

{% block content %}
<div class="container">
    <br>
    
    <h2>Student Login Form</h2>
    <br>
    <form method="POST" action="">
        {% csrf_token %}
        {% if messages %}
            {% for message in messages %}
            <div class="alert alert-danger" role="alert">
                {{ message }}
            </div>
            {% endfor %}
            
        {% endif %} <br>

        {% for field in form %} 
           <p>{{ field.label }} </p>
           <p>{{ field }} </p> 
           <br>
        {% endfor %} 
        
        <br>
        <input type="submit" class="btn btn-primary" value="Login">
    </form>
    
</div>
{% endblock %} 

I have been trying to change again and again but form.is_valid() is still returning False. I could not figure out the reason that the form is not valid because I have already specify the fields that I want to show and added the csrf_token. Could anyone help me to figure out where is the problem?

можете, пожалуйста, изменить эту строку

form = StudentLoginForm(data=request.POST)

to

form = StudentLoginForm(request.POST)

а также зачем вы проверяете поля, ведь вы уже проверяете их с помощью .is_valid() функцию?

Попробуйте использовать простую форму, а не ModelForm, так как ModelForm в фоновом режиме работают с созданием и обновлением объектов.

В этом случае ModelForm проверяется, как будто вы пытаетесь создать новый Student, что приводит к ошибкам already exists.

Например, вы можете написать простую форму входа в систему следующим образом:

class StudentLoginForm(forms.Form):
    username = forms.CharField(widget=forms.TextInput(attrs={'autofocus': True}))
    password = forms.CharField(
        label='Password',
        strip=False,
        widget=forms.PasswordInput,
    )

А затем в своих представлениях используйте его как есть:

def student_login(request):
    form = StudentLoginForm()
    if request.method == 'POST':
        form = StudentLoginForm(data=request.POST)
        
        if form.is_valid():
            user = authenticate(
                username=form.cleaned_data.get('username'),
                password=form.cleaned_data.get('password'),
            )

            if user:
                login(request, user)
                return redirect('index')

        messages.error(request, 'Invalid username or password!')

    context = {'form':form}
    return render(request,'student_login.html',context)

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

Лучше использовать встроенную модель User, предоставляемую django. Если вы хотите расширить поля в модели User, используйте AbstractUser и переопределите модель User. Смотрите в документации https://docs.djangoproject.com/en/3.2/topics/auth/customizing/

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