[Fixed]-Django. Error message for login form

61👍

Because the form has no idea an error occurred.

When you construct the form here:

form=LoginForm()

You’re constructing it without passing it any information. It doesn’t know anything about the POST the user just did, or that the the login failed, or that the password was missing, or whatever the error was.

Here’s what my login forms look like:

class LoginForm(forms.Form):
    username = forms.CharField(max_length=255, required=True)
    password = forms.CharField(widget=forms.PasswordInput, required=True)

    def clean(self):
        username = self.cleaned_data.get('username')
        password = self.cleaned_data.get('password')
        user = authenticate(username=username, password=password)
        if not user or not user.is_active:
            raise forms.ValidationError("Sorry, that login was invalid. Please try again.")
        return self.cleaned_data

    def login(self, request):
        username = self.cleaned_data.get('username')
        password = self.cleaned_data.get('password')
        user = authenticate(username=username, password=password)
        return user

We override the form’s clean method, so that if the form passes validation we can check the user’s credentials. We also put a login method on the form object itself, to make our view cleaner.

Next, in our view, we want to do this:

def login_view(request):
    form = LoginForm(request.POST or None)
    if request.POST and form.is_valid():
        user = form.login(request)
        if user:
            login(request, user)
            return HttpResponseRedirect("/n1.html")# Redirect to a success page.
    return render(request, 'enter.html', {'login_form': form })

We instantiate the form and hand it the request.POST to check against.

If we have a POST, we check if the form is valid. The form’s “clean” method will get called, and check the user credentials for us.

If the credentials fail, we raise an error, which we need to show in our template.

Errors raised by the form (but not attached to a field) are stored in non_field_errors, which can be displayed like so:

{% if form.non_field_errors %}
    <ul class='form-errors'>
        {% for error in form.non_field_errors %}
            <li>{{ error }}</li>
        {% endfor %}
    </ul>
{% endif %}

1👍

When you redirect, I’m not sure you send the context of your page. So when you redirect to the /login/ page, django tinks it’s a new form which is loaded.

Leave a comment