Middleware
- Explore Django Middleware and learn how to modify request and response cycles.
What is Middleware?
Middleware is a layer between:
Request (Browser → Django)
Response (Django → Browser)It processes every request and response globally.
Middleware can:
Modify request before view runs
Modify response before sending to user
Block requests
Add extra data
Perform logging, authentication, security
Django Request–Response Cycle
Browser Request
↓
Middleware (Request Phase)
↓
URL Dispatcher
↓
View
↓
Middleware (Response Phase)
↓
Browser Response
Why Middleware is Used?
Built-in Django Middleware Examples
Found in settings.py:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
]
These are executed top to bottom for requests
Bottom to top for responsesHow Middleware Works Internally
Each middleware is a Python class with:
__init__() → Runs once
__call__() → Runs on every request
Optional methods:
process_view()
process_exception()
process_template_response()
Middleware Structure (Modern Django)
Basic Middleware Structure
class ExampleMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# Code before view
response = self.get_response(request)
# Code after view
return response
Description
get_response → Next middleware/view
Code before → request phase
Code after → response phase
Custom Middleware
What is Custom Middleware?
Custom middleware is developer-defined logic that runs on every request.
Examples:
Log user activity
Block unauthenticated users
Track request time
Restrict access by time/IP
Steps to Create Custom Middleware
Step 1. Create Middleware File
your_app/
├── middleware.py
Simple Request Logger Middleware
Request Logger Middleware
middleware.py
import datetime
class RequestLoggerMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
print(f"Request Path: {request.path}")
print(f"Request Time: {datetime.datetime.now()}")
response = self.get_response(request)
return response
Description
Logs every request path
Executes before view runs
Register Middleware in settings.py
MIDDLEWARE = [
'your_app.middleware.RequestLoggerMiddleware',
]
Block Access for Anonymous Users
Login Required Middleware
middleware.py
from django.shortcuts import redirect
class LoginRequiredMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if not request.user.is_authenticated and request.path != '/login/':
return redirect('/login/')
return self.get_response(request)
Description
Checks authentication
Redirects to login if not logged in
Applies globally
Use carefully (may affect admin/static files)
Execution Time Middleware
Request Execution Time Middleware
middleware.py
import time
class ExecutionTimeMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
start_time = time.time()
response = self.get_response(request)
end_time = time.time()
print("Execution Time:", end_time - start_time)
return response
- IP Blocking Middleware
IP Restriction Middleware
middleware.py
from django.http import HttpResponseForbidden
BLOCKED_IPS = ['192.168.1.10']
class IPBlockMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
ip = request.META.get('REMOTE_ADDR')
if ip in BLOCKED_IPS:
return HttpResponseForbidden("Access Denied")
return self.get_response(request)
Using process_view (Advanced)
Middleware with process_view
class ViewLoggerMiddleware:
def process_view(self, request, view_func, view_args, view_kwargs):
print("View Called:", view_func.__name__)
return None
Runs before view execution
Middleware Order (Very Important Concept)
MIDDLEWARE = [
'MiddlewareA',
'MiddlewareB',
'MiddlewareC',
]
Execution:
Request: A → B → C
Response: C → B → A
Middleware vs Decorator