Show errors in login form

2.2k Views Asked by At

I've created a user login page, and it works great! But when the user inputs the wrong credentials, how can I show an error on the login page? I tried usign an if and a variable, but that resulted in the error being shown no matter what.

In my views, I've set the "error_message" variable like so:

def LoginView(request):
    error_message = ''
    logout(request)
    context = RequestContext(request)
    username = request.POST.get('username')
    password = request.POST.get('password')
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            return HttpResponseRedirect("/")
        else:
            # Return a 'disabled account' error message
            return HttpResponseRedirect("/")
    else:
        # Return an 'invalid login' error message
  --->  error_message = "Incorrect username or password."
    return render(request, 'profile/login.html', {'error_message': error_message}, context)

However, in my template, this variable is displayed no matter what, even if I set the variable inside the "if" statement.

Here's my template:

{% include '__header.html' %}
<style>
main {
    width: 920px;
    background: none;
    margin-top: calc(50vh - 280px)
}
</style>

<div class="form-container">
<form id="user" method="post" action="/login/" 
enctype="multipart/form-data" class="text">
    {% csrf_token %}
    <div class="title">Login to your account</div>
    <div class="form-col">
        <div class="field-container">
            <div class="field-input-container">
                <div class="field-label">Username</div>
                <div class="field-input">
                    <input class="field-input-element" type="text" name="username"/>
                </div>
            </div>
        <div class="field-help"></div>
        </div>
    </div>
    <div class="form-col">
        <div class="field-container" style="height: 110px">
            <div class="field-input-container">
                <div class="field-label">Password</div>
                <div class="field-input">
                <input class="field-input-element" type="password" name="password"/>
                </div>
            </div>
        <div class="field-error">{{ error_message }}</div>
        <div class="field-help"></div>
        </div>
    </div>
    <div class="form-button-container">
    <input type="submit" name="submit" value="Login" class="button form-button"/>
    </div>
</form> 
</div>

{% include '__footer.html' %}

So, how can I show an error message in the template only if there has been an error?


Updated code based off answers (still does same thing)

def LoginView(request):
    template_name='profile/login.html'
    logout(request)
    context = RequestContext(request)

    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect("/")
            else:
                # Return a 'disabled account' error message
                return HttpResponseRedirect("/")
        else:
            # Return an 'invalid login' error message
            error_message = "Incorrect username or password."
    else:
        error_message = ''

    return render(request, 'profile/login.html', {'error_message': error_message}, context)
3

There are 3 best solutions below

4
On BEST ANSWER

The logic that you have for checking the users details should only be done if they've posted the form so you can wrap this part in an if request.method == 'POST'

if request.method == 'POST':
    username = request.POST.get('username')
    password = request.POST.get('password')
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            return HttpResponseRedirect("/")
        else:
            # Return a 'disabled account' error message
            return HttpResponseRedirect("/")
    else:
        # Return an 'invalid login' error message
        error_message = "Incorrect username or password."

You might also want to wrap your error div in a

{% if error_message %}
3
On

Here's an example that could be useful for you, first import and inside your view declare a template name :

from django.contrib import messages

template_name='your_app/login.html' #Inside the login view

Then, after login fails :

messages.error(request, "incorrect user or password")

And last, render the template :

return render(request, self.template_name,{"form_group" : form_group})

Hope it helps.

0
On

Your immediate problem is that you are setting your error message for GET and POST requests. You should only show it for POST requests, after the user has submitted data.

if request.method == "POST":
    username = request.POST.get('username')
    password = request.POST.get('password')
    user = authenticate(username=username, password=password)
    if user is not None:
        ...
    else:
        # Return an 'invalid login' error message
        error_message = "Incorrect username or password."