Skip links

Jody Boucher

Software Engineer

Django Middleware: An overview of middleware

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 HttpRequest.

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:

Django middleware overview diagram Diagram of example middleware in relation to other Django components

Enabling middleware

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 MIDDLEWARE setting 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.

Short-circuiting execution

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.

Further details

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 processtemplateresponse().