User Login and Logout in Django

Django is a High-Level Web Framework and it has lots of built-in features. We can use those built-in functions for our common use of Web Application. Some of the functions are Permission and User Control, Signals, Templates, Django ORM, Access Control List, etc. Out of this Registration App, is a good example and a good thing about it is that the features can be used out-of-the-box.

Authenticate, Login and Logout

Django authentication framework (django.contrib.auth) provides authenticate() and login() functions whose job is to authenticate and login users respectively.

The authenticate() function accepts two keyword arguments, username and password and returns an object of type User, if username and password are valid. Otherwise, it returns None.

Syntax:

authenticate(request=None,**credentials)
  • This is used to verify the set of credentials as keyword arguments, username and password for the default case, checks them against each authentication backend, and returns a User object if the credentials are valid for the user object.
  • The authenticate() function only verifies whether the credentials provided are valid or not. It doesn’t login the user.
  • request is an optional HttpRequest which is passed on the authenticate method of the authentication backend.

To login user we use login() function. It takes two arguments, request object (HttpRequest) and a User object. To login user it saves the user’s ID in the session, using Django session framework.

Once a user is logged in, he should be able to logout and this is the responsibility of logout() function.

Syntax:

login(request,user,backend=None)
  • To log a User in, from a view, use login(). It takes an HttpRequest object and a User object. login() saves the User ID in the Session using Django’s Session Framework.
  • When a User log’s in, the User’s ID and the backend that was used for authentication are saved in the user’s session. This allows the same authentication backend to fetch the user’s details on a future request.

To logout users we use logout() function. It accepts a request (HttpRequest) object and returns None. Calling logout() function completely deletes the session data associated with the logged in user.

It is important to note that calling logout() function doesn’t throw any errors if the user is not logged in.

The logout() function also removes the cookie from the browser.

Syntax:

logout(request)
  • To log out a user who has been logged in via django.contrib.auth.login(), use django.contrib.auth.logout() within your view. It takes an HttpRequest object has no return value.
  • When you call logout(), the session data for the current request is completely cleaned out. All existing data is removed. This is to prevent another person from using the same Web browser to log in and to have access to the previous user’s session data.

Django ModelForm Example Overview

We will be doing the following in this Django ModelForm Example

  • Create a Page for entry of User Details(UserName, First name, Last name, Email, Password, Confirm Password) and save it into the database(which will be done automatically by model forms).
  • Have login option to for an existing user
  • Show details after login and then logout option.

Create the project according to the following tree:

Coding the app

  • As usual, we need to deal with some data(UserName, First name, Last name, Email, Password, Confirm Password). So, we need to create the forms.py accordingly:
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

class SignUpForm(UserCreationForm):
    class Meta:
        model = User
        fields = ['username','first_name','last_name','email']
        labels = {'email':'Email'}
  • Also, add your application in the installed_apps of settings.py

Making Migrations

  • Make sure that the shell is navigated into the app folder and run the following command.
python manage.py makemigrations
  • Next, run the command below to actually implement it into the database.
python manage.py migrate

Configuring the view

  • Yes, the class-based views reduce our efforts to quite an extent.
  • So, look for the file views.py in your app folder and add the following code:
from django.shortcuts import render, HttpResponseRedirect
from django.contrib import messages
from .forms import SignUpForm
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import authenticate,login,logout
# Create your views here.
#Signup
def sign_up(request):
    if request.method == "POST":
        fm = SignUpForm(request.POST)
        if fm.is_valid():
            messages.success(request,'Account Created Successfully!!!')
            fm.save()
    else:
        fm = SignUpForm()
    return render(request,'enroll/signup.html',{'form':fm})


#Login
def user_login(request):
    if not request.user.is_authenticated:

        if request.method == "POST":
            fm = AuthenticationForm(request=request,data=request.POST)
            if fm.is_valid():
                uname = fm.cleaned_data['username']
                upass = fm.cleaned_data['password']
                user = authenticate(username=uname, password=upass)
                if user is not None:
                    login(request,user)
                    messages.success(request,'Logged in successfully!!!')
                    return HttpResponseRedirect('/profile/')
        else:
            fm = AuthenticationForm()
        return render(request,'enroll/userlogin.html',{'form':fm})
    else:
        return HttpResponseRedirect('/profile/')


#Profile
def user_profile(request):
    if request.user.is_authenticated:
        return render(request,'enroll/profile.html',{'name':request.user})
    else:
        return HttpResponseRedirect('/login/')


#Logout
def user_logout(request):
    logout(request)
    return HttpResponseRedirect('/login/')

Creating UI for Django ModelForm

  • Now, in the templates folder, create another directory named enroll and it should be like /enroll/templates/enroll/.
  • In the enroll folder present in the templates directory, create a new HTML file called signup.html and add the following code:-
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>User Registration</title>
</head>
<body>
 <form action="" method="post" novalidate>
     {% csrf_token %}
     {% if form.non_field_errors %}
        {% for error in form.non_field_errors %}
            <p class="er">{{error}}</p>
        {% endfor %}
     {% endif %}
     {% for fm in form %}
        {{fm.label_tag}} {{fm}} {{fm.errors|striptags}} <br><br>
     {% endfor %}
     <input type="submit" value="Submit">
 </form>
{% if messages %}
    {% for message in messages %}
        <small {% if message.tags %} class="{{message.tags}}" {% endif %}></small>
    {% endfor%}
{% endif %}
<a href="{% url 'login' %}">Login</a>
</body>
</html>
  • In the same directory, create another HTML file named userlogin.html and add the code below:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>User Login</title>
    <style>
        .er{
        color:red;
        }
    </style>
</head>
<body>
<form action="" method="post" novalidate>
    {% csrf_token %}
    {% if form.non_field_errors %}
        {% for error in form.non_field_errors %}
            <p class="er">{{error}}</p>
        {% endfor %}
    {% endif %}
    {% for fm in form %}
        {{fm.label_tag}} {{fm}} {{fm.errors|striptags}} <br><br>
    {% endfor %}
    <input type="submit", value="Login">
</form>
    <a href="{% url 'signup' %}">Signup</a>
</body>
</html>
  • In the same directory, create another HTML file named profile.html and add the code below:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>User Profile</title>
</head>
<body>
<h1>Welcome {{user}}</h1>
{% if messages %}
    {% for message in messages %}
        <small {% if message.tags %} class="{{message.tags}}" {% endif %}>{{message}}</small>
    {% endfor %}
{% endif %}
<a href="{% url 'logout' %}">Logout</a>
</body>
</html>

Configuring the urls.py

  • To redirect our website to certain pages we need to make the following changes in the urls.py file:
from django.contrib import admin
from django.urls import path
from enroll import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('signup/',views.sign_up, name='signup'),
    path('login/',views.user_login, name='login'),
    path('profile/',views.user_profile,name='profile'),
    path('logout/',views.user_logout,name='logout'),
]

Running the app

  • Now let’s try running the app. Make sure your development server is running. If not you can use the following command in your Windows PowerShell to run your development server.
python manage.py runserver
  • If you are a new user you need to signup:

  • If you are an existing user you can click on login option”

  • If you do not enter the correct credentials, the following message will pop up:

  • On entering the correct credentials you will be redirected to the profile page:

  • If a user wants to visit the profile page without login he will be redirected to the login page
  • After login and redirecting to the profile page, he can click the logout option then he will be redirected to the login page.