Erin Allard Erin Allard - 6 months ago 50
HTML Question

Login form doesn't render for custom Django login page

Django newbie here trying to create a custom login form, view and template. My problem is that the logic in my view is causing the form to not be displayed, and instead, the error message from the else statement always shows up. I'm sure I'm missing something, I just have no idea what it is. Can anyone point me in the right direction? I have been working from the Django docs and this tutorial: http://www.djangobook.com/en/2.0/chapter14.html Thank you!

UPDATE: User @AKS pointed out that I wasn't handling the POST/GET logic properly, so I accepted this as the answer. Once I adjusted my code, the form still wouldn't display, so I discovered some errors in the HTML file and fixed them. The corrected code is shown at the bottom of this post.

-- views.py --

# Django imports
from django import forms
from django.contrib import auth
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.contrib.auth.views import login, logout
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone

# Local Django imports
from .models import *
from .forms import *


def login(request, method='POST'):
'''Shows a login form and a registration link.'''

username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password)

if user is not None and user.is_active:
auth.login(request, user)
return HttpResponseRedirect("client/items")

else:
return HttpResponse("Invalid login. Please try again.")

return render(request, "registration/login.html", {'next':'/client/items'})


-- registration/login.html --

{% extends "registration/base.html" %}

{% block content %}

{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}

<form method="post" action='/login'>{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>

<input type="submit" value="Login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>

{% endblock %}


-- settings.py --

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'clients'
]

MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]


-- app/urls.py --

from django.conf.urls import url
from . import views

urlpatterns = [
url(r'^$', views.login, name='login'),
url(r'^register$', views.register, name='register'),
url(r'^client/items$', views.client_items, name='client_items'),
url(r'^client/new_item$', views.new_item, name='new_item'),
url(r'^client/edit_item$', views.edit_item, name='edit_item'),
url(r'^client/item_detail$', views.item_detail, name='item_detail'),
]


-- Corrected registration/login.html --

{% extends "registration/base.html" %}

{% block content %}

{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}

<form method="post" action=''>{% csrf_token %}
<label for="username">Username:</label>
<input type="text" name="username" value="" id="username"><br>
<label for="password">Password:</label>
<input type="password" name="password" value="" id="password"><br>

<input type="submit" value="Login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>

{% endblock %}

AKS AKS
Answer

It seems the execution never reaches the last return statement because it is either satisfying if condition, else it returns the Invalid Login response.

if user is not None and user.is_active:
    auth.login(request, user)
    return HttpResponseRedirect("client/items")

else:
    return HttpResponse("Invalid login. Please try again.")

return render(request, "registration/login.html", {'next':'/client/items'})

It seems you need to process the form in POST request and return the login form in case of GET request:

def login(request, method='POST'):
    '''Shows a login form and a registration link.'''

    if request.method == 'POST':
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        user = auth.authenticate(username=username, password=password)

        if user is not None and user.is_active:
            auth.login(request, user)
            return HttpResponseRedirect("client/items")

        else:
            return HttpResponse("Invalid login. Please try again.")

    # if not POST then return login form    
    return render(request, "registration/login.html", {'next':'/client/items'})
Comments