Jim
Jim

Reputation: 14280

Django Form Errors Won't Display

I've built a "firewall" login form that I want to put in front of my actual production website while I develop the site. The idea is to try and keep the "bad guys" out of the site and at the same time see what usernames and passwords they're using. The problem I'm having is that if I enter an invalid username/password pair, my form's error message doesn't get displayed. I realize that for my purposes, it it might be better to not display any error message at all but I'd still like to understand what the problem is. Can anyone see what I'm doing wrong?

Thanks.

# views.py
import logging
logger = logging.getLogger(__name__)
from django.contrib.auth import authenticate
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.views import login
from django.http import HttpResponseRedirect

def firewall_login(request, *args, **kwargs):
    if request.method == "POST":
        form = AuthenticationForm(request, data=request.POST)
        username = request.POST['username']
        password = request.POST['password']
        if form.is_valid():
            fw_username = form.cleaned_data['username']
            fw_password = form.cleaned_data['password']
            user = authenticate(username=fw_username, password=fw_password)
            if user is not None:
                if user.is_active:
                    login(request, user)
                    logger.info("User '%s' logged in." % fw_username)
                    return HttpResponseRedirect("/accounts/profile/")
                else:
                    logger.info("User '%s' tried to log in to disabled account." % fw_username)
                    return HttpResponseRedirect("/accounts/disabled/")
        else:
            logger.info("User '%s' tried to log in with password '%s'." % (username, password))
            form = AuthenticationForm(request)   # Display bound form
    else:
        form = AuthenticationForm()   # Display unbound form
    return render(request, "registration/login.html", {"form": form,})

# login.html
{% extends "base.html" %}
{% block content %}

    {% if form.errors %}
    <p class="alert alert-error">Sorry, that's not a valid username or password</p>
    {% endif %}

    {% if form.errors %}
        {% for field in form %}
            {% for error in field.errors %}
                <div class="alert alert-error">
                    <strong>{{ error|escape }}</strong>
                </div>
            {% endfor %}
        {% endfor %}
        {% for field in form.non_field_errors %}
            <div class="alert alert-error">
                <strong>{{ error|escape }}</strong>
            </div>
        {% endfor %}
    {% endif %}

    <form action="" method="post">
        {% csrf_token %}
        <p><label for="username">Username:</label>{{ form.username }}</p>
        <p><label for="password">Password:</label>{{ form.password }}</p>
        <input type="hidden" name="next" value="{{ next|escape }}" />
        <input class="btn btn-primary" type="submit" value="login" />
    </form>

{% endblock %}

Upvotes: 1

Views: 1864

Answers (1)

Dmitry Egerev
Dmitry Egerev

Reputation: 516

It's because you pass new form instance. Validation occurs on is_valid call.

So, just remove form = AuthenticationForm(request) in else block:

def firewall_login(request, *args, **kwargs):
    if request.method == "POST":
        form = AuthenticationForm(request, data=request.POST)
        username = request.POST['username']
        password = request.POST['password']
        if form.is_valid():
            fw_username = form.cleaned_data['username']
            fw_password = form.cleaned_data['password']
            user = authenticate(username=fw_username, password=fw_password)
            if user is not None:
                if user.is_active:
                    login(request, user)
                    logger.info("User '%s' logged in." % fw_username)
                    return HttpResponseRedirect("/accounts/profile/")
                else:
                    logger.info("User '%s' tried to log in to disabled account." % fw_username)
                    return HttpResponseRedirect("/accounts/disabled/")
        else:
            logger.info("User '%s' tried to log in with password '%s'." % (username, password))
    else:
        form = AuthenticationForm()   # Display unbound form
    return render(request, "registration/login.html", {"form": form,})

Upvotes: 2

Related Questions