#

## Django documentation

# Middleware

Middleware is a framework of hooks into Django's request/response processing. It's a light, low-level "plugin" system for globally altering Django's input and/or output.

Each middleware component is responsible for doing some specific function. For example, Django includes a middleware component, `XViewMiddleware`, that adds an `"X-View"` HTTP header to every response to a `HEAD` request.

This document explains all middleware components that come with Django, how to use them, and how to write your own middleware.

## Activating middleware

To activate a middleware component, add it to the `MIDDLEWARE_CLASSES` list in your Django settings. In `MIDDLEWARE_CLASSES`, each middleware component is represented by a string: the full Python path to the middleware's class name. For example, here's the default `MIDDLEWARE_CLASSES` created by `django-admin.py startproject`:

    MIDDLEWARE_CLASSES = (
        "django.middleware.common.CommonMiddleware",
        "django.middleware.doc.XViewMiddleware",
    )

Django applies middleware in the order it's defined in `MIDDLEWARE_CLASSES`, except in the case of response and exception middleware, which is applied in reverse order.

A Django installation doesn't require any middleware -- e.g., `MIDDLEWARE_CLASSES` can be empty, if you'd like -- but it's strongly suggested that you use `CommonMiddleware`.

## Available middleware

### django.middleware.cache.CacheMiddleware

Enables site-wide cache. If this is enabled, each Django-powered page will be cached for as long as the `CACHE_MIDDLEWARE_SECONDS` setting defines. See the cache documentation.

### django.middleware.common.CommonMiddleware

Adds a few conveniences for perfectionists:

- Forbids access to user agents in the `DISALLOWED_USER_AGENTS` setting, which should be a list of strings.

- Performs URL rewriting based on the `APPEND_SLASH` and `PREPEND_WWW` settings. If `APPEND_SLASH` is `True`, URLs that lack a trailing slash will be redirected to the same URL with a trailing slash. If `PREPEND_WWW` is `True`, URLs that lack a leading "www." will be redirected to the same URL with a leading "www."

  Both of these options are meant to normalize URLs. The philosophy is that each URL should exist in one, and only one, place. Technically a URL `foo.com/bar` is distinct from `foo.com/bar/` -- a search-engine indexer would treat them as separate URLs -- so it's best practice to normalize URLs.

- Handles ETags based on the `USE_ETAGS` setting. If `USE_ETAGS` is set to `True`, Django will calculate an ETag for each request by MD5-hashing the page content, and it'll take care of sending `Not Modified` responses, if appropriate.

### django.middleware.doc.XViewMiddleware

Sends custom `X-View` HTTP headers to HEAD requests that come from IP addresses defined in the `INTERNAL_IPS` setting. This is used by Django's automatic documentation system.

### django.middleware.gzip.GZipMiddleware

Compresses content for browsers that understand gzip compression (all modern browsers).

### django.middleware.http.ConditionalGetMiddleware

Handles conditional GET operations. If the response has a `ETag` or `Last-Modified` header, and the request has `If-None-Match` or `If-Modified-Since`, the response is replaced by an HttpNotModified.

Also removes the content from any response to a HEAD request and sets the `Date` and `Content-Length` response-headers.

### django.middleware.sessions.SessionMiddleware

Enables session support. See the session documentation.

## Writing your own middleware

Writing your own middleware is easy. Each middleware component is a single Python class that defines one or more of the following methods:

### process_request

Interface: `process_request(self, request)`

`request` is an `HttpRequest` object. This method is called on each request, before Django decides which view to execute.

`process_request()` should return either `None` or an `HttpResponse` object. If it returns `None`, Django will continue processing this request, executing any other middleware and, then, the appropriate view. If it returns an `HttpResponse` object, Django won't bother calling ANY other middleware or the appropriate view; it'll return that `HttpResponse`.

### process_view

Interface: `process_view(self, request, view_func, param_dict)`

`request` is an `HttpRequest` object. `view_func` is the Python function that Django is about to use. (It's the actual function object, not the name of the function as a string.) `param_dict` is a dictionary of keyword arguments that will be passed to the view -- NOT including the first argument (`request`).

`process_view()` is called just before Django calls the view. It should return either `None` or an `HttpResponse` object. If it returns `None`, Django will continue processing this request, executing any other `process_view()` middleware and, then, the appropriate view. If it returns an `HttpResponse` object, Django won't bother calling ANY other middleware or the appropriate view; it'll return that `HttpResponse`.

### process_response

Interface: `process_response(self, request, response)`

`request` is an `HttpRequest` object. `response` is the `HttpResponse` object returned by a Django view.

`process_response()` should return an `HttpResponse` object. It could alter the given `response`, or it could create and return a brand-new `HttpResponse`.

### process_exception

Interface: `process_exception(self, request, exception)`

`request` is an `HttpRequest` object. `exception` is an `Exception` object raised by the view function.

Django calls `process_exception()` when a view raises an exception. `process_exception()` should return either `None` or an `HttpResponse` object. If it returns an `HttpResponse` object, the response will be returned to the browser. Otherwise, default exception handling kicks in.

### Guidelines

> - Middleware classes don't have to subclass anything.
> - The middleware class can live anywhere on your Python path. All Django cares about is that the `MIDDLEWARE_CLASSES` setting includes the path to it.
> - Feel free to look at Django's available middleware for examples. The default Django middleware classes are in `django/middleware/` in the Django distribution.
> - If you write a middleware component that you think would be useful to other people, contribute to the community! Let us know, and we'll consider adding it to Django.

## Comments

## Post a comment

Note: Please only use the comments for questions/critcisms/suggestions on the docs; if you experience errors please file a ticket, ask in the IRC channel, or post to the django-users list. Comments will be periodically reviewed, integrated into the documentation proper, and removed.

Your name:

Comment: