Sitemap

Django_010: Simple Login and Logout with Built-in Authentication

7 min readJun 6, 2025

--

In this post, I am going to provide the most basic and simple form of login and logout using Django’s built-in methods: authenticate, login, and logout. I’ve kept it as minimal as possible to focus on the core concepts, without any CSS or fancy pages, just the essential functionality for login and logout.

Basic Explanation

Goal: A simple Django app with login/logout using Django’s built-in authentication.

Key Functions:

  • authenticate(request, username, password): Verifies user credentials.
  • login(request, user): Starts a user session.
  • logout(request): Ends the user session.

Flow:

  • Home page shows login status.
  • Login page accepts username/password, uses authenticate and login.
  • Logout ends the session with logout and redirects to home.

Step 1: Create and Set Up the Project

Run these commands in your terminal (Linux/Mac) or command prompt (Windows), you can check my previous posts for complete guide.

python -m venv env
source env/bin/activate # Windows: env\Scripts\activate
pip install django
django-admin startproject myproject
cd myproject
python manage.py startapp accounts
python manage.py migrate
python manage.py createsuperuser # Create a user (e.g., username: testuser, password: testpass123)

Step 2: Project Files

Create or replace the following files in the myproject directory. I’ll list each file’s content and its path clearly.

File: myproject/settings.py

In myproject/settings.py, add ‘accounts’ to INSTALLED_APPS to register the accounts app, allowing Django to recognize its models, views, and URLs. In the TEMPLATES setting, add ‘DIRS’: [‘templates’] to tell Django to look for template files in the myproject/templates/ directory.

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'accounts', # Our app
]

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['templates'], # Look for templates in project-level templates folder
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth', # For user info in templates
'django.contrib.messages.context_processors.messages', # For error messages
],
},
},
]

File: myproject/urls.py

In myproject/urls.py, include path(‘’, include(‘accounts.urls’)) in urlpatterns to route all requests starting with the root URL (/) to the URLs defined in the accounts app, enabling the app’s URL patterns to handle requests like /login/ and /logout/.

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('accounts.urls')), # Route to accounts app
]

File: accounts/urls.py

In accounts/urls.py, define urlpatterns with path(‘’, views.home, name=’home’) to route the root URL (/) to the home view,

  • path(‘login/’, views.login_view, name=’login’) to route /login/ to the login view,
  • path(‘logout/’, views.logout_view, name=’logout’) to route /logout/ to the logout view, mapping URLs to their respective view functions in the accounts app.
from django.urls import path
from . import views

urlpatterns = [
path('', views.home, name='home'), # Home page
path('login/', views.login_view, name='login'), # Login page
path('logout/', views.logout_view, name='logout'), # Logout action
]

File: accounts/views.py

In accounts/views.py, the file defines view functions that handle HTTP requests for the home page, login, and logout processes in the accounts app.

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

def home(request):
return render(request, 'home.html')

def login_view(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
messages.error(request, 'Invalid username or password.')
return render(request, 'login.html')

def logout_view(request):
logout(request)
return redirect('home')

1. home View

  • This is the simplest view that just displays the home page
  • render() takes the request and a template name ('home.html') and returns that page to the user
  • It doesn’t require any authentication — anyone can see the home page

2. login_view View

At the end of this post, I’ve included a complete guide to the authenticate() process in Django.

This handles user login with several steps:

  1. Checks if the request method is POST (form submission)

2. Gets the username and password from the submitted form data

3. Uses Django’s authenticate() to verify credentials:

  • If valid: authenticate() returns a User object
  • If invalid: returns None

4. For valid users:

  • login() creates a user session (logs them in)
  • Redirects to the home page

5. For invalid credentials:

  • Shows an error message using Django’s messaging framework

6. For GET requests (initial page load) or after failed login:

  • Shows the login form page (‘login.html’)

3. logout_view View

This handles user logout:

  1. Calls Django’s logout() function which:
  • Ends the user’s session
  • Clears their authentication data

2. Redirects them back to the home page

File: templates/base.html (Create a templates folder in the myproject directory)

<!DOCTYPE html>
<html>
<head>
<title>Simple Auth</title>
</head>
<body>
{% if user.is_authenticated %}
<p>Hello, {{ user.username }}! <a href="{% url 'logout' %}">Logout</a></p>
{% else %}
<p><a href="{% url 'login' %}">Login</a></p>
{% endif %}
{% block content %}
{% endblock %}
</body>
</html>

In templates/base.html, this file serves as the base template that other templates—such as home.html and login.html—extend. It provides a common layout, including a navigation section.

The code {% if user.is_authenticated %}<p>Hello, {{ user.username }}! <a href="{% url 'logout' %}">Logout</a></p>{% else %}<p><a href="{% url 'login' %}">Login</a></p>{% endif %} checks whether the user is logged in:

  • If user.is_authenticated is True, it displays the username along with a logout link.
  • If it is False, it shows a login link instead.

The user.is_authenticated variable is part of Django’s authentication system. It is made available in templates by the django.contrib.auth.context_processors.auth context processor, which is listed in myproject/settings.py under TEMPLATES['OPTIONS']['context_processors']. This processor ensures the user object—with authentication status and user details—is accessible in all templates when a request is processed.

Get CodeAddict’s stories in your inbox

Join Medium for free to get updates from this writer.

File: templates/home.html

{% extends 'base.html' %}
{% block content %}
<h1>Home</h1>
{% if user.is_authenticated %}
<p>You are logged in!</p>
{% else %}
<p>You are not logged in.</p>
{% endif %}
{% endblock %}

File: templates/login.html

{% extends 'base.html' %}
{% block content %}
<h1>Login</h1>
{% if messages %}
{% for message in messages %}
<p style="color: red;">{{ message }}</p>
{% endfor %}
{% endif %}
<form method="post">
{% csrf_token %}
<label>Username:</label>
<input type="text" name="username">
<label>Password:</label>
<input type="password" name="password">
<button type="submit">Login</button>
</form>
{% endblock %}

Step 3: Run the Project

python manage.py runserver

Step 4: Test the App

  • Open http://127.0.0.1:8000/ in your browser.
  • Home Page: Shows if you’re logged in or not.
  • Login Page: Go to /login/, use the superuser credentials (e.g., testuser/testpass123).
  • Logout: Click the “Logout” link when logged in to end the session.

Additional Explanation (Advanced): Django Authentication

Predefined Functions in Django

  1. authenticate() - Django's built-in authentication function
  • Location: django.contrib.auth.authenticate
  • Purpose: Verifies user credentials against the database
  • Returns: User object if valid, None if invalid

2. login() - Django's session creation function

  • Location: django.contrib.auth.login
  • Purpose: Creates a persistent user session
  • Stores session data in the database and browser cookies

3. logout() - Django's session termination function

  • Location: django.contrib.auth.logout
  • Purpose: Destroys the user session

How Authentication Works Step-by-Step

1. Database Setup (Behind the Scenes)

Django automatically creates these important tables during migration:

  • auth_user — Stores all user accounts (username, password hash, email, etc.)
  • auth_session — Stores active user sessions

2. The Authentication Process

When a user submits the login form:

  1. Form Submission (POST request)
username = request.POST['username'] 
password = request.POST['password']
  • The browser sends the username and password to the server

2. Credential Verification

user = authenticate(request, username=username, password=password)
  • Django queries the auth_user table for the username
  • If found, it hashes the provided password and compares it with the stored hash
  • Password hashing uses PBKDF2 by default (with salt and multiple iterations)

3. User Object Creation

  • If credentials match, Django returns a User object containing: => User ID, Username, Email, First/last name, Permissions, Other profile data

4. Session Creation

login(request, user)
  • Creates a session record in the auth_session table
  • Sets a session cookie in the browser containing the session ID
  • The session ID is a random, hard-to-guess string

5. Database Operations

  • For authentication:
SELECT * FROM auth_user WHERE username = '[provided_username]';
  • For session creation:
INSERT INTO auth_session (session_key, session_data, expire_date) VALUES ('random_session_id', 'encrypted_session_data', 'expiration_time');

3. Session Management

After successful login: Each subsequent request includes the session cookie

Django:

  1. Reads the session ID from the cookie
  2. Looks it up in the auth_session table
  3. Attaches the authenticated user to the request object (available as request.user)

5. Logout Process

logout(request)
  1. Deletes the session record from the database
  2. Tells the browser to expire the session cookie
  3. Clears the user data from the request object

Customization Options

While Django provides these defaults, you can customize:

  1. Authentication Backends — To authenticate against different sources (LDAP, etc.)
  2. User Model — To add custom fields to users
  3. Password Hashers — To use different hashing algorithms
  4. Session Engine — To store sessions in cache or other systems

The beauty of Django’s auth system is that it handles all these complex security concerns for you while providing sensible defaults that work for most applications.

How Django Authentication Connects Users, Views, and Templates (Step-by-Step)

The {% if user.is_authenticated %} in templates/base.html checks if a user is logged in, and the user object is sent to templates through Django’s authentication system. Here’s a simple explanation of the process and where users are created:

User Creation:
- Users are created in the database using Django’s authentication system (django.contrib.auth). You create a user via python manage.py createsuperuser (for admins) or through code/models (e.g., User.objects.create_user(username='testuser', password='testpass123')). These users are stored in the database table managed by Django’s auth.User model.

Authentication Process:
- In accounts/views.py, the login_view uses authenticate(request, username, password) to verify the user’s credentials against the database.
If valid, login(request, user) creates a session, marking the user as authenticated and attaching their User object to the request.

Sending User to Templates:
— In myproject/settings.py, the TEMPLATES setting includes 'django.contrib.auth.context_processors.auth' in context_processors.
This context processor automatically adds the user object (containing is_authenticated and details like username) to every template’s context when a view renders a template (e.g., render(request, 'home.html')).

As a result, {% if user.is_authenticated %} in base.html can check if the user is logged in and access user.username.

Flow Summary:

  1. User is created in the database (via createsuperuser or code).
  2. User logs in via login_view, which authenticates and sets the session.
  3. The auth context processor in settings.py sends the user object to templates.
  4. Templates use user.is_authenticated to show content based on login status.

--

--

CodeAddict

Written by CodeAddict

Research Professor, Ph.D. | 15+ yrs engineering across 8 fields. I bring AI into any of them. bridge-ai-studio.netlify.app