What is Middleware?
Middleware is Django's processing mechanism for requests and responses. Each middleware component performs a specific task on every request or response.
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',
]
Middleware runs in order from top to bottom for requests, and bottom to top for responses.
Creating Custom Middleware
Custom middleware lets you add behavior to every request or response in your application.
class TimingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
start_time = time.time()
response = self.get_response(request)
duration = time.time() - start_time
response['X-Request-Duration'] = str(duration)
return response
The __init__ method receives the get_response callable. The __call__ method processes the request and returns the response.
Middleware Hooks
Middleware can implement process_view, process_exception, and process_template_response methods.
class ViewLogMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print(f'View: {view_func.__name__}')
def process_exception(self, request, exception):
print(f'Exception: {exception}')
return None
process_view runs after URL resolution but before the view. process_exception runs when a view raises an exception.
Built-in Middleware
Django includes several built-in middleware classes for common tasks.
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
Each middleware serves a specific purpose: security headers, session management, CSRF protection, authentication, and messages.
Middleware Order Matters
The order of middleware in MIDDLEWARE affects how requests are processed.
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'myapp.middleware.TimingMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
]
Place custom middleware after session and auth middleware if it depends on request.user or request.session. Test your middleware order carefully.