A beginner guide to Django’s middleware

Abhijeet kumar
Django Unleashed
Published in
3 min readJul 23, 2024

Django, a high-level Python web framework, is designed to promote rapid development and clean, pragmatic design.

One of its most powerful features is middleware, which provides a way to process requests globally before they reach the view or after the view has processed them.

In this blog, we’ll explore what middleware is, how it works, and how you can create your custom middleware in Django.

Middleware

Middleware in Django as a chain of filters or handlers that sit between the web server and your Django views.

When a user makes a request, middleware can inspect or modify the request before it reaches your view, and it can also inspect or modify the response before it’s sent back to the user.

It’s a way to add extra features or processing to our web application without changing the core logic of your views.

Middleware Works

When a request is made to a Django application, it passes through a series of middleware components before reaching the view.

After the view processes the request and returns a response, the response goes back through the middleware components in reverse order.

Here’s a simplified view of the middleware flow —

Built-in Middleware

Django comes with several built-in middleware classes that handle common tasks —

SecurityMiddleware — Enhances the security of your web application.

SessionMiddleware Manages sessions across requests.

CommonMiddleware — Provides various enhancements, such as URL rewriting.

CsrfViewMiddleware — Adds protection against Cross-Site Request Forgeries.

AuthenticationMiddleware — Associates users with requests using sessions.

MessageMiddleware — Manages messages between requests.

Creating Custom Middleware

Creating custom middleware in Django is straightforward. A middleware class is a regular Python class that defines one or more of the following methods:

1. __init__(self, get_response) — Called once when the web server starts.

2. __call__(self, request) — Called for each request. It should return a response.

3. process_view(self, request, view_func, view_args, view_kwargs) — Called just before Django calls the view. It should return either None or an HttpResponse.

4. process_exception(self, request, exception) — Called if the view raises an exception. It should return either None or an HttpResponse.

5. process_template_response(self, request, response) — Called just after the view has finished executing if the response contains a render() method.

Custom Middleware

Here’s a simple example of custom middleware that logs each request’s path and method —

import logging

class RequestLogMiddleware:
def __init__(self, get_response):
self.get_response = get_response
self.logger = logging.getLogger(__name__)

def __call__(self, request):
# Code to be executed for each request before the view (and later middleware) are called.
self.logger.info(f'Request path: {request.path} - Method: {request.method}')
print('process_request called right now')

response = self.get_response(request)

# Code to be executed for each request/response after the view is called.
return response

def process_template_response(self, request, response):
# This is executed if the view returns a TemplateResponse
print('process_template_response')
return response

def process_exception(self, request, exception):
# This is executed if an exception occurs while processing the request
print('process_exception')
self.logger.error(f'Exception occurred: {exception}')
return None

Adding Middleware —

To add your custom middleware to a Django project, you need to include it in the MIDDLEWARE setting in your settings.py file —

MIDDLEWARE = [
# Default Django middleware
'django.middleware.security.SecurityMiddleware',
'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',
# Your custom middleware replace your_project name with your middleware file
'your_project.middleware.RequestLogMiddleware',
]

Conclusion

Middleware in Django is a powerful tool that allows developers to process requests and responses globally.

It’s essential for handling cross-cutting concerns like security, session management, and logging.

By understanding how middleware works and how to create custom middleware, you can extend the functionality of your Django applications in a clean and modular way.

👋 Hey there…

Your appreciation or feedback on this insight would be greatly valued, whether it’s a small follow up or leaving a note.

And connect with me on Twitter handler for the tech insights.
Looking forward to engaging with you!

--

--