Django User authentication Login - Logout

Print

In this Post, we will add user authentication functionality for our Django application. We need to have a url, view and a template for it.

In main urls.py file, import crmapp views and a new path for login.

from django.contrib import admin
from django.urls import path, include
from crmapp import views as crmapp_views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('crmapp/', include('crmapp.urls') ),
    path('loginuser/', crmapp_views.loginuser, name='loginuser')
]

 

 In crmapp's views.py, import redirectauthenticate, login and logout. Then create a new view for login.

 If we look at the view below, we are taking form data by using request.POST[] and assign it to variable.

We pass these variables to authenticate method and create an object with the provided username and password data. If this object is not empty, login() uses that object along with HttpRequest object and saves the user’s ID in the session, using Django’s session framework.

from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth import authenticate, login, logout

def loginuser(request):
    if request.method == 'POST':
        user_name = request.POST['form_username']
        pass_word = request.POST['form_password']
        user_obj = authenticate(request, username = user_name, password= pass_word)
        if userobj is not None:
            login(request, userobj)
            return redirect('crmapp')
        else:
            return redirect('loginuser')
    else:
        return render(request, 'loginuser.html', {})

 

 

We also need a template (html file) for login in which we display a form for username and password. Create a file named loginuser.html in crmapp's template folder.

 

{% extends 'base.html' %}

{% block title %}
{% endblock title %}

{% block content %}
<div class="container">
    <center>
    <h1>Login</h1>
    <form method="POST">
        {% csrf_token %}
            <div class="col-3 row align-items-center">
                <input type="text" class="form-control col-sm" placeholder="Enter Username" name="form_username">
            </div>
            <div class="col-3 row align-items-center">
                <input type="password" class="form-control col-sm" placeholder="Enter Password" name="form_password">
            </div>
            <div class="col-1 row align-items-center mt-2">
                <button type="submit" class="btn btn-primary">Login</button>
            </div>
    </form>
</center>
</div>
{% endblock content %}

 

 

We already created a button for Login on our Navbar but it does not have the url. Lets create it. Open base.html

Change this line:

<a class="btn btn-outline-secondary" href="#">Login</a>

 

To This:

<a class="btn btn-outline-secondary" href="/{% url 'loginuser' %}">Login</a>

 

 

 

 

Django Messages:

If Logon Fails, we are redirected back to loginuser.html. It will be nice if we generate a message for the user if authentication fails.

Open views.py and import messages

Then add messages.success just before the redirect as below. I am using extra_tags to be able to show different colored messages on success or fail.

from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages

def loginuser(request):
    if request.method == 'POST':
        user_name = request.POST['form_username']
        pass_word = request.POST['form_password']
        user_obj = authenticate(request, username = user_name, password= pass_word)
        if user_obj is not None:
            login(request, user_obj)
            return redirect('crmapp')
        else:
            messages.success(request, "Wrong username or password", extra_tags='red')
            return redirect('loginuser')
    else:
        return render(request, 'loginuser.html', {})

def crmapp(request):
    msg = "Hello"
    return render(request, 'crmapp.html', {'welcome_msg':msg})

 

Finally we need to modify base.html. We should display the value of messages if there is any. The most proper place to show the message would be right after the Navbar and before the closing </head> tag.

If there is any message for loop will display all the messages and if tags is red the message will be red, if not it will be green

    <!--Navbar Ends-->
    <div class="container">
        {% if messages %}
            {% for m in messages%}
                {% if 'red' in m.tags %}
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
                        {{m}}
                    <button type="button" class="close btn-sm" data-dismiss="alert" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                    </button>
                    </div>
                {% else %}
                    <div class="alert alert-success alert-dismissible fade show" role="alert">
                        {{m}}
                    <button type="button" class="close btn-sm" data-dismiss="alert" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                    </button>
                    </div>
                {% endif %}
            {% endfor %}
        {% endif %}
    </div>

  </head>

 

 

 

 

 

 

 

Logout:

For Logout functionality I just need a url, view. 

Add this to mail urls.py file

path('logoutuser/', crmapp_views.logoutuser, name='logoutuser'),

 

And create a view for logout.

def logoutuser(request):
    logout(request)
    messages.success(request, "You are logged out successfully", extra_tags='green')
    return redirect('loginuser')

 

 The navigation bar has the button for Log out but it does not have the link. Let's add it.

<a class="dropdown-item" href="/{% url 'logoutuser' %}">Logout</a>

 

 Test it.