user.is_authenticated always returns False for inactive users on template


In my template, login.html, I have:

{% if form.errors %}
    {% if user.is_authenticated %}
    <div class="alert alert-warning"><center>Your account doesn't have access to this utility.</center></div>
    {% else %}
    <div class="alert alert-warning"><center>Incorrect username or password!</center></div>
    {% endif %}
{% endif %}

What I am trying to do is, if after form submission, user is inactive then display a different error message and if user is simply not authenticated then display Incorrect username password error message. This doesn't work. It always displays "Incorrect username or password!" in both the cases. However inside a view, user.is_authenticated returns True even for inactive users.

I there any other wway to get this done? I also tried

{% if 'inactive' in form.errors %}

But this doesnt work too, even though when I try to print form.errors, it shows text "This account is inactive" for inactive users.

EDIT: For view, I am simply using django's login view inside a custom login view

from django.contrib.auth.views import login, logout
from django.shortcuts import render, redirect

def custom_login(request, **kwargs):
    if request.user.is_authenticated():
        return redirect('/homepage/')
        return login(request, **kwargs)

There isn't any point checking {% if user.is_authenticated %} in your login template. If the user is authenticated, then your custom_login view would have redirected them to the homepage.

If the account is inactive, then the form will be invalid and the user will not be logged in. The forms's errors will look like:

{'__all__': [u'This account is inactive.']}

Therefore checking {% if 'inactive' in form.errors %} will not work, because the error is stored with the key __all__, not inactive.

You could do {% if 'This account is inactive.' in form.non_field_errors %} but this is very fragile, and would break if Django ever changed the text of the error message for inactive users.

It would be better to display the actual errors, rather than trying to find out what sort of error it is in the template. The easiest way to display non-field errors is to include:

{{ form.non_field_errors }}

Or, if you need more control:

{% for error in form.non_field_errors %}
    {{ error }}
{% endfor %}

If you need to change the error message for inactive users, you can subclass the authentication form, then use that in your login view.

my_error_messages = AuthenticationForm.error_messages.copy()
my_error_messages['inactive'] = 'My custom message'

class MyAuthenticationForm(AuthenticationForm):
    error_messages = my_error_messages

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at


Login to comment