wickstopher
wickstopher

Reputation: 999

Beginner Django: Authenticating/logging in a User

Hello! I'm having trouble with the authentication system. I've followed the documentation pretty closely, but I just can't seem to get this to work. The problem seems to be that when I call the authenticate method with my cleaned form data, it's not returning anything. It's clearly doing this in the web page (it just returns the render request at the bottom every time I submit the form), and I tried authenticating in the same way via the shell and am also returning True for 'user is None'.

I'm wondering if perhaps the problem is that I haven't included the proper middleware? My MIDDLEWARE_CLASSES are as follows:

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

It appears that I have everything necessary, but I'm just not sure.

In any case, here's the code for my view:

from django.shortcuts import render
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth.models import User
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import authenticate, login  

def user_login(request):
    if request.method == 'POST':
        form = AuthenticationForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            user = authenticate(username=username, password=password)

            if user is not None:
                if user.is_active:
                    login(request, user)
                    return HttpResponse("Good Job")
                else:
                    return HttpResponse("Inactive User")
            else:
                return HttpResponse("Bad Job")
    else:
        form = AuthenticationForm()
    return render(request, 'myapp/login_form.html', {
        'form': form,
    })

And here is my very simple login_form.html template:

<h1>Login</h1>

<form action="/login/" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>

UPDATE: I have implemented the following solution:

changed the line

form = AuthenticationForm(request.POST)

to

form = AuthenticationForm(data = request.POST)

Now I am able to login via the superuser account, but username/password combinations for ordinary accounts are not recognized. If I submit the credentials for a regular user, the form is re-rendered plus the following message:

Please enter a correct username and password. Note that both fields may be case-sensitive.

Any ideas?

UPDATE 2 It turns out I had an error in my registration form such that it wasn't properly storing the password for new users registered via that form. I was doing password assignment in the constructor for a new User object, when instead you need to:

User.objects.create_user('username', 'email', 'password')

Rookie mistake! Thanks for the help.

Upvotes: 1

Views: 743

Answers (1)

Tito
Tito

Reputation: 44

Try form = AuthenticationForm(data = request.POST)

From the django git for AuthenticationForm:

def __init__(self, request=None, *args, **kwargs):
            """The 'request' parameter is set for custom auth use by subclasses.
                The form data comes in via the standard 'data' kwarg.`

            """

Upvotes: 2

Related Questions