The Django web framework contains hooks enabling a global mechanism for modifying the request and/or response in between the web-server interface and the view. Django middleware are the components that make use of these hooks.
An example of Django middleware is a component that adds a
user attribute to each incoming
This post provides an overview of middleware in the Django web framework.
Note: This post refers to the style of middleware introduced with Django 1.10. For syntax and details on middleware prior to version 1.10 refer to the Django documentation.
How middleware fits into the request/response cycle
Django middleware runs between Django receiving a request and processing the view, and again between view processing and serving the response from the web-server interface. The following diagram gives a high level view of middleware interaction with other components:
A middleware component is enabled by specifying the Python dotted path of the middleware’s factory method or class in the
MIDDLEWARE setting. The
MIDDLEWARE setting generated by the
django-admin startproject command provides a good example of how middleware is specified.
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', ]
Ordering middleware execution
The order in which middleware are defined in the
MIDDLEWARE setting determines the order that Django applies the middleware during the request/response phases:
- Middleware is applied in the order define by the
MIDDLEWAREsetting during the request phase.
- During the response phase middleware is applied in the reverse order.
Some middleware depend on processing done in other middleware so it is important to order middleware correctly. The
MIDDLEWARE setting generated by
django-admin startproject shows the proper ordering for the default middleware. If you intend to include other middleware please review the Django docs for information on dependencies between the various middleware classes.
The basic model on which all middleware operates expects each middleware to call the
get_response callable in order to pass execution to the next middleware or to the view middleware if there are no further middleware in the chain.
A middleware implemented using a class will have the following basic structure:
class SampleMiddleware(object): def __init__(self, get_response): self.get_response = get_response # One-time configuration and initialization. def __call__(self, request): # Code to be executed in the request processing phase # Let the get_response callable pass processing to # the next middleware response = self.get_response(request) # Code to be executed in the response processing phase return response
Returning a response without calling
get_response short-circuits middleware execution. In this case, later middleware is not called for processing of either the request or response phase. View processing also does not occur. The same middleware (in reverse order) that the request was processed through is given an opportunity to process the response.
A few other hooks are available for class-based middleware that allow some deviation from the basic pattern described here. Refer to the Django documentation for further details on additional middleware hooks: process_view(), process_exception() and process_template_response().