Django is a powerful web framework that simplifies web development. One of its most versatile features is middleware—a powerful mechanism for processing requests and responses globally. In this blog, we’ll explore what middleware is, how it works, and how you can create custom middleware in Django.
What is Middleware in Django?

Middleware is a framework of hooks into Django’s request/response processing. It is essentially a function or a class that sits between the request (sent by a user) and the response (returned by the server). Middleware can modify requests before they reach the view and alter responses before they are sent to the client.
Django provides several built-in middleware components that handle common tasks, such as authentication, security, and session management.
How Middleware Works:
Django processes middleware in a specific order defined in the MIDDLEWARE
setting of settings.py
. The middleware functions run in two phases:
- Request Phase: Before Django calls the view, middleware can process the request and modify it or even return a response before reaching the view.
- Response Phase: After the view processes the request, middleware can modify the response before sending it back to the client.
Built-in Middleware in Django:
Django comes with several middleware classes by default. Some important ones include:
SecurityMiddleware
: Enhances security by adding headers likeX-Content-Type-Options
andStrict-Transport-Security
.AuthenticationMiddleware
: Associates users with requests using sessions.SessionMiddleware
: Enables session management.CommonMiddleware
: Provides various utilities like URL rewriting and handling conditional GET responses.
Creating Custom Middleware in Django:
Django allows developers to create custom middleware to perform specific actions. Let’s go step by step and create a simple middleware that logs request details.
Step 1: Create a Middleware Class:
Inside your Django app, create a new file middleware.py
(if it doesn’t exist) and define your middleware:
import datetime
class RequestLoggerMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# Log request details before passing it to the view
print(f"[{datetime.datetime.now()}] Request: {request.method} {request.path}")
response = self.get_response(request)
# Log response details
print(f"[{datetime.datetime.now()}] Response Status: {response.status_code}")
return response
Step 2: Add Middleware to Django Settings:
Once the middleware is created, register it in settings.py
under the MIDDLEWARE
list:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'yourapp.middleware.RequestLoggerMiddleware', # Add your custom middleware here
]
Step 3: Test the Middleware:
Now, when you make a request to your Django application, you should see logs in the console showing request and response details.
Use Cases of Custom Middleware:
Custom middleware can be useful for various tasks, including:
- Logging request/response data
- Restricting access based on IP
- Injecting custom headers
- Implementing maintenance mode
- Performance monitoring and debugging
Conclusion:
Django middleware is a powerful tool that allows you to process requests and responses globally in your application. By leveraging built-in middleware or creating custom ones, you can enhance security, logging, and overall functionality. Understanding middleware is essential for any Django developer looking to build efficient and maintainable applications.
Do you have any custom middleware use cases? Feel free to share your thoughts in the comments!