summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorFlorian Apolloner <florian@apolloner.eu>2015-11-07 16:12:37 +0100
committerTim Graham <timograham@gmail.com>2016-05-17 07:22:22 -0400
commit9baf692a58de78dba13aa582098781675367c329 (patch)
tree1926555441d0c3b13185782dce193b839d616a4a /docs
parent05c888ffb843ba3eff06cd07b3cef5bbb513a54f (diff)
Fixed #26601 -- Improved middleware per DEP 0005.
Thanks Tim Graham for polishing the patch, updating the tests, and writing documentation. Thanks Carl Meyer for shepherding the DEP.
Diffstat (limited to 'docs')
-rw-r--r--docs/howto/auth-remote-user.txt4
-rw-r--r--docs/howto/error-reporting.txt4
-rw-r--r--docs/ref/applications.txt4
-rw-r--r--docs/ref/checks.txt12
-rw-r--r--docs/ref/clickjacking.txt4
-rw-r--r--docs/ref/contrib/admin/index.txt4
-rw-r--r--docs/ref/contrib/flatpages.txt5
-rw-r--r--docs/ref/contrib/messages.txt8
-rw-r--r--docs/ref/contrib/redirects.txt8
-rw-r--r--docs/ref/contrib/sites.txt4
-rw-r--r--docs/ref/csrf.txt8
-rw-r--r--docs/ref/middleware.txt30
-rw-r--r--docs/ref/request-response.txt12
-rw-r--r--docs/ref/settings.txt20
-rw-r--r--docs/ref/utils.txt4
-rw-r--r--docs/releases/1.10.txt11
-rw-r--r--docs/releases/1.5.txt3
-rw-r--r--docs/topics/auth/default.txt2
-rw-r--r--docs/topics/auth/index.txt2
-rw-r--r--docs/topics/cache.txt12
-rw-r--r--docs/topics/http/_images/middleware.graffle957
-rw-r--r--docs/topics/http/_images/middleware.svg3
-rw-r--r--docs/topics/http/middleware.txt325
-rw-r--r--docs/topics/http/sessions.txt10
-rw-r--r--docs/topics/http/urls.txt4
-rw-r--r--docs/topics/i18n/timezones.txt5
-rw-r--r--docs/topics/i18n/translation.txt12
-rw-r--r--docs/topics/testing/tools.txt6
28 files changed, 311 insertions, 1172 deletions
diff --git a/docs/howto/auth-remote-user.txt b/docs/howto/auth-remote-user.txt
index 1680baa92b..5bfe210458 100644
--- a/docs/howto/auth-remote-user.txt
+++ b/docs/howto/auth-remote-user.txt
@@ -29,10 +29,10 @@ Configuration
First, you must add the
:class:`django.contrib.auth.middleware.RemoteUserMiddleware` to the
-:setting:`MIDDLEWARE_CLASSES` setting **after** the
+:setting:`MIDDLEWARE` setting **after** the
:class:`django.contrib.auth.middleware.AuthenticationMiddleware`::
- MIDDLEWARE_CLASSES = [
+ MIDDLEWARE = [
'...',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.RemoteUserMiddleware',
diff --git a/docs/howto/error-reporting.txt b/docs/howto/error-reporting.txt
index d07404a1e9..7a51338539 100644
--- a/docs/howto/error-reporting.txt
+++ b/docs/howto/error-reporting.txt
@@ -57,7 +57,7 @@ not found" errors). Django sends emails about 404 errors when:
* :setting:`DEBUG` is ``False``;
-* Your :setting:`MIDDLEWARE_CLASSES` setting includes
+* Your :setting:`MIDDLEWARE` setting includes
:class:`django.middleware.common.BrokenLinkEmailsMiddleware`.
If those conditions are met, Django will email the users listed in the
@@ -78,7 +78,7 @@ behavior is from broken Web bots too.
before other middleware that intercepts 404 errors, such as
:class:`~django.middleware.locale.LocaleMiddleware` or
:class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware`.
- Put it towards the top of your :setting:`MIDDLEWARE_CLASSES` setting.
+ Put it towards the top of your :setting:`MIDDLEWARE` setting.
You can tell Django to stop reporting particular 404s by tweaking the
:setting:`IGNORABLE_404_URLS` setting. It should be a list of compiled
diff --git a/docs/ref/applications.txt b/docs/ref/applications.txt
index be761505fe..53d9bcd9b5 100644
--- a/docs/ref/applications.txt
+++ b/docs/ref/applications.txt
@@ -37,8 +37,8 @@ projects.
Applications include some combination of models, views, templates, template
tags, static files, URLs, middleware, etc. They're generally wired into
projects with the :setting:`INSTALLED_APPS` setting and optionally with other
-mechanisms such as URLconfs, the :setting:`MIDDLEWARE_CLASSES` setting, or
-template inheritance.
+mechanisms such as URLconfs, the :setting:`MIDDLEWARE` setting, or template
+inheritance.
It is important to understand that a Django application is just a set of code
that interacts with various parts of the framework. There's no such thing as
diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt
index e4af02c1a2..5057ef18b6 100644
--- a/docs/ref/checks.txt
+++ b/docs/ref/checks.txt
@@ -491,19 +491,19 @@ The following checks are run if you use the :option:`check --deploy` option:
* **security.W001**: You do not have
:class:`django.middleware.security.SecurityMiddleware` in your
- :setting:`MIDDLEWARE_CLASSES` so the :setting:`SECURE_HSTS_SECONDS`,
+ :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES` so the :setting:`SECURE_HSTS_SECONDS`,
:setting:`SECURE_CONTENT_TYPE_NOSNIFF`, :setting:`SECURE_BROWSER_XSS_FILTER`,
and :setting:`SECURE_SSL_REDIRECT` settings will have no effect.
* **security.W002**: You do not have
:class:`django.middleware.clickjacking.XFrameOptionsMiddleware` in your
- :setting:`MIDDLEWARE_CLASSES`, so your pages will not be served with an
+ :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`, so your pages will not be served with an
``'x-frame-options'`` header. Unless there is a good reason for your
site to be served in a frame, you should consider enabling this
header to help prevent clickjacking attacks.
* **security.W003**: You don't appear to be using Django's built-in cross-site
request forgery protection via the middleware
(:class:`django.middleware.csrf.CsrfViewMiddleware` is not in your
- :setting:`MIDDLEWARE_CLASSES`). Enabling the middleware is the safest
+ :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`). Enabling the middleware is the safest
approach to ensure you don't leave any holes.
* **security.W004**: You have not set a value for the
:setting:`SECURE_HSTS_SECONDS` setting. If your entire site is served only
@@ -540,7 +540,7 @@ The following checks are run if you use the :option:`check --deploy` option:
sessions.
* **security.W011**: You have
:class:`django.contrib.sessions.middleware.SessionMiddleware` in your
- :setting:`MIDDLEWARE_CLASSES`, but you have not set
+ :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`, but you have not set
:setting:`SESSION_COOKIE_SECURE` to ``True``. Using a secure-only session
cookie makes it more difficult for network traffic sniffers to hijack user
sessions.
@@ -554,7 +554,7 @@ The following checks are run if you use the :option:`check --deploy` option:
sessions.
* **security.W014**: You have
:class:`django.contrib.sessions.middleware.SessionMiddleware` in your
- :setting:`MIDDLEWARE_CLASSES`, but you have not set
+ :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`, but you have not set
:setting:`SESSION_COOKIE_HTTPONLY` to ``True``. Using an ``HttpOnly`` session
cookie makes it more difficult for cross-site scripting attacks to hijack user
sessions.
@@ -571,7 +571,7 @@ The following checks are run if you use the :option:`check --deploy` option:
deployment.
* **security.W019**: You have
:class:`django.middleware.clickjacking.XFrameOptionsMiddleware` in your
- :setting:`MIDDLEWARE_CLASSES`, but :setting:`X_FRAME_OPTIONS` is not set to
+ :setting:`MIDDLEWARE`/:setting:`MIDDLEWARE_CLASSES`, but :setting:`X_FRAME_OPTIONS` is not set to
``'DENY'``. The default is ``'SAMEORIGIN'``, but unless there is a good reason
for your site to serve other parts of itself in a frame, you should change
it to ``'DENY'``.
diff --git a/docs/ref/clickjacking.txt b/docs/ref/clickjacking.txt
index abac81dcd8..2f72e18d2f 100644
--- a/docs/ref/clickjacking.txt
+++ b/docs/ref/clickjacking.txt
@@ -56,9 +56,9 @@ Setting ``X-Frame-Options`` for all responses
To set the same ``X-Frame-Options`` value for all responses in your site, put
``'django.middleware.clickjacking.XFrameOptionsMiddleware'`` to
-:setting:`MIDDLEWARE_CLASSES`::
+:setting:`MIDDLEWARE`::
- MIDDLEWARE_CLASSES = [
+ MIDDLEWARE = [
...
'django.middleware.clickjacking.XFrameOptionsMiddleware',
...
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index eed7d4451c..66b116ad35 100644
--- a/docs/ref/contrib/admin/index.txt
+++ b/docs/ref/contrib/admin/index.txt
@@ -41,8 +41,8 @@ For reference, here are the requirements:
defined in your :setting:`TEMPLATES` as well as
:class:`django.contrib.auth.middleware.AuthenticationMiddleware` and
:class:`django.contrib.messages.middleware.MessageMiddleware` to
- :setting:`MIDDLEWARE_CLASSES`. (These are all active by default, so
- you only need to do this if you've manually tweaked the settings.)
+ :setting:`MIDDLEWARE`. These are all active by default, so you only need to
+ do this if you've manually tweaked the settings.
4. Determine which of your application's models should be editable in the
admin interface.
diff --git a/docs/ref/contrib/flatpages.txt b/docs/ref/contrib/flatpages.txt
index 3326a93ea8..580f864c34 100644
--- a/docs/ref/contrib/flatpages.txt
+++ b/docs/ref/contrib/flatpages.txt
@@ -53,7 +53,7 @@ Then either:
or:
3. Add ``'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'``
- to your :setting:`MIDDLEWARE_CLASSES` setting.
+ to your :setting:`MIDDLEWARE` setting.
4. Run the command :djadmin:`manage.py migrate <migrate>`.
@@ -144,8 +144,7 @@ can do all of the work.
methods. Only requests which are successfully routed to a view via
normal URL resolution apply view middleware.
-Note that the order of :setting:`MIDDLEWARE_CLASSES` matters. Generally, you
-can put
+Note that the order of :setting:`MIDDLEWARE` matters. Generally, you can put
:class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware` at the
end of the list. This means it will run first when processing the response, and
ensures that any other response-processing middlewares see the real flatpage
diff --git a/docs/ref/contrib/messages.txt b/docs/ref/contrib/messages.txt
index d425899cd9..414cf21116 100644
--- a/docs/ref/contrib/messages.txt
+++ b/docs/ref/contrib/messages.txt
@@ -27,14 +27,14 @@ already contains all the settings required to enable message functionality:
* ``'django.contrib.messages'`` is in :setting:`INSTALLED_APPS`.
-* :setting:`MIDDLEWARE_CLASSES` contains
+* :setting:`MIDDLEWARE` contains
``'django.contrib.sessions.middleware.SessionMiddleware'`` and
``'django.contrib.messages.middleware.MessageMiddleware'``.
The default :ref:`storage backend <message-storage-backends>` relies on
:doc:`sessions </topics/http/sessions>`. That's why ``SessionMiddleware``
must be enabled and appear before ``MessageMiddleware`` in
- :setting:`MIDDLEWARE_CLASSES`.
+ :setting:`MIDDLEWARE`.
* The ``'context_processors'`` option of the ``DjangoTemplates`` backend
defined in your :setting:`TEMPLATES` setting contains
@@ -42,8 +42,8 @@ already contains all the settings required to enable message functionality:
If you don't want to use messages, you can remove
``'django.contrib.messages'`` from your :setting:`INSTALLED_APPS`, the
-``MessageMiddleware`` line from :setting:`MIDDLEWARE_CLASSES`, and the
-``messages`` context processor from :setting:`TEMPLATES`.
+``MessageMiddleware`` line from :setting:`MIDDLEWARE`, and the ``messages``
+context processor from :setting:`TEMPLATES`.
Configuring the message engine
==============================
diff --git a/docs/ref/contrib/redirects.txt b/docs/ref/contrib/redirects.txt
index 2aadf8a45c..8af48ba8b2 100644
--- a/docs/ref/contrib/redirects.txt
+++ b/docs/ref/contrib/redirects.txt
@@ -18,7 +18,7 @@ To install the redirects app, follow these steps:
:ref:`is installed <enabling-the-sites-framework>`.
2. Add ``'django.contrib.redirects'`` to your :setting:`INSTALLED_APPS` setting.
3. Add ``'django.contrib.redirects.middleware.RedirectFallbackMiddleware'``
- to your :setting:`MIDDLEWARE_CLASSES` setting.
+ to your :setting:`MIDDLEWARE` setting.
4. Run the command :djadmin:`manage.py migrate <migrate>`.
How it works
@@ -49,9 +49,9 @@ given ``old_path`` with a site ID that corresponds to the
The middleware only gets activated for 404s -- not for 500s or responses of any
other status code.
-Note that the order of :setting:`MIDDLEWARE_CLASSES` matters. Generally, you
-can put :class:`~django.contrib.redirects.middleware.RedirectFallbackMiddleware`
-at the end of the list, because it's a last resort.
+Note that the order of :setting:`MIDDLEWARE` matters. Generally, you can put
+:class:`~django.contrib.redirects.middleware.RedirectFallbackMiddleware` at the
+end of the list, because it's a last resort.
For more on middleware, read the :doc:`middleware docs
</topics/http/middleware>`.
diff --git a/docs/ref/contrib/sites.txt b/docs/ref/contrib/sites.txt
index 2f312d04e0..ec2c1bf2b2 100644
--- a/docs/ref/contrib/sites.txt
+++ b/docs/ref/contrib/sites.txt
@@ -405,8 +405,8 @@ If you often use this pattern::
there is simple way to avoid repetitions. Add
:class:`django.contrib.sites.middleware.CurrentSiteMiddleware` to
-:setting:`MIDDLEWARE_CLASSES`. The middleware sets the ``site`` attribute on
-every request object, so you can use ``request.site`` to get the current site.
+:setting:`MIDDLEWARE`. The middleware sets the ``site`` attribute on every
+request object, so you can use ``request.site`` to get the current site.
How Django uses the sites framework
===================================
diff --git a/docs/ref/csrf.txt b/docs/ref/csrf.txt
index f59b45646d..277fd85720 100644
--- a/docs/ref/csrf.txt
+++ b/docs/ref/csrf.txt
@@ -27,10 +27,10 @@ How to use it
To take advantage of CSRF protection in your views, follow these steps:
-1. The CSRF middleware is activated by default in the
- :setting:`MIDDLEWARE_CLASSES` setting. If you override that setting, remember
- that ``'django.middleware.csrf.CsrfViewMiddleware'`` should come before any
- view middleware that assume that CSRF attacks have been dealt with.
+1. The CSRF middleware is activated by default in the :setting:`MIDDLEWARE`
+ setting. If you override that setting, remember that
+ ``'django.middleware.csrf.CsrfViewMiddleware'`` should come before any view
+ middleware that assume that CSRF attacks have been dealt with.
If you disabled it, which is not recommended, you can use
:func:`~django.views.decorators.csrf.csrf_protect` on particular views
diff --git a/docs/ref/middleware.txt b/docs/ref/middleware.txt
index 49062d3474..1e582d5724 100644
--- a/docs/ref/middleware.txt
+++ b/docs/ref/middleware.txt
@@ -77,6 +77,36 @@ issued by the middleware.
* Sends broken link notification emails to :setting:`MANAGERS` (see
:doc:`/howto/error-reporting`).
+Exception middleware
+--------------------
+
+.. module:: django.middleware.exception
+ :synopsis: Middleware to return responses for exceptions.
+
+.. class:: ExceptionMiddleware
+
+.. versionadded:: 1.10
+
+Catches exceptions raised during the request/response cycle and returns the
+appropriate response.
+
+* :class:`~django.http.Http404` is processed by
+ :data:`~django.conf.urls.handler404` (or a more friendly debug page if
+ :setting:`DEBUG=True <DEBUG>`).
+* :class:`~django.core.exceptions.PermissionDenied` is processed
+ by :data:`~django.conf.urls.handler403`.
+* ``MultiPartParserError`` is processed by :data:`~django.conf.urls.handler400`.
+* :class:`~django.core.exceptions.SuspiciousOperation` is processed by
+ :data:`~django.conf.urls.handler400` (or a more friendly debug page if
+ :setting:`DEBUG=True <DEBUG>`).
+* Any other exception is processed by :data:`~django.conf.urls.handler500`
+ (or a more friendly debug page if :setting:`DEBUG=True <DEBUG>`).
+
+Django uses this middleware regardless of whether or not you include it in
+:setting:`MIDDLEWARE`, however, you may want to subclass if your own middleware
+needs to transform any of these exceptions into the appropriate responses.
+:class:`~django.middleware.locale.LocaleMiddleware` does this, for example.
+
GZip middleware
---------------
diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt
index 64bd5960cd..96f5300f8b 100644
--- a/docs/ref/request-response.txt
+++ b/docs/ref/request-response.txt
@@ -176,9 +176,9 @@ All attributes should be considered read-only, unless stated otherwise.
An instance of :class:`~django.urls.ResolverMatch` representing the
resolved URL. This attribute is only set after URL resolving took place,
- which means it's available in all views but not in middleware methods
- which are executed before URL resolving takes place (like
- ``process_request()``, you can use ``process_view()`` instead).
+ which means it's available in all views but not in middleware which are
+ executed before URL resolving takes place (you can use it in
+ :meth:`process_view` though).
Attributes set by application code
----------------------------------
@@ -210,7 +210,7 @@ Attributes set by middleware
Some of the middleware included in Django's contrib apps set attributes on the
request. If you don't see the attribute on a request, be sure the appropriate
-middleware class is listed in :setting:`MIDDLEWARE_CLASSES`.
+middleware class is listed in :setting:`MIDDLEWARE`.
.. attribute:: HttpRequest.session
@@ -257,7 +257,9 @@ Methods
behind multiple proxies. One solution is to use middleware to rewrite
the proxy headers, as in the following example::
- class MultipleProxyMiddleware(object):
+ from django.django.utils.deprecation import MiddlewareMixin
+
+ class MultipleProxyMiddleware(MiddlewareMixin):
FORWARDED_FOR_FIELDS = [
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED_HOST',
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index 838dde808a..a7801f715c 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -77,7 +77,7 @@ can be used as a subdomain wildcard: ``'.example.com'`` will match
``example.com``. A value of ``'*'`` will match anything; in this case you are
responsible to provide your own validation of the ``Host`` header (perhaps in a
middleware; if so this middleware must be listed first in
-:setting:`MIDDLEWARE_CLASSES`).
+:setting:`MIDDLEWARE`).
Django also allows the `fully qualified domain name (FQDN)`_ of any entries.
Some browsers include a trailing dot in the ``Host`` header which Django
@@ -1844,6 +1844,17 @@ Example: ``"http://media.example.com/"``
:setting:`MEDIA_URL` and :setting:`STATIC_URL` must have different
values. See :setting:`MEDIA_ROOT` for more details.
+.. setting:: MIDDLEWARE
+
+``MIDDLEWARE``
+--------------
+
+.. versionadded:: 1.10
+
+Default:: ``None``
+
+A list of middleware to use. See :doc:`/topics/http/middleware`.
+
.. setting:: MIDDLEWARE_CLASSES
``MIDDLEWARE_CLASSES``
@@ -1856,7 +1867,11 @@ Default::
'django.middleware.csrf.CsrfViewMiddleware',
]
-A list of middleware classes to use. See :doc:`/topics/http/middleware`.
+A list of middleware classes to use. This was the default setting used in
+Django 1.9 and earlier. Django 1.10 introduced a new style of middleware. If
+you have an older project using this setting you should :ref:`update any
+middleware you've written yourself <upgrading-middleware>` to the new style
+and then use the :setting:`MIDDLEWARE` setting.
.. setting:: MIGRATION_MODULES
@@ -3312,6 +3327,7 @@ HTTP
* :setting:`DISALLOWED_USER_AGENTS`
* :setting:`FORCE_SCRIPT_NAME`
* :setting:`INTERNAL_IPS`
+* :setting:`MIDDLEWARE`
* :setting:`MIDDLEWARE_CLASSES`
* Security
diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt
index f95ff1017f..1b527277af 100644
--- a/docs/ref/utils.txt
+++ b/docs/ref/utils.txt
@@ -173,6 +173,10 @@ The functions defined in this module share the following properties:
middleware functionality on a per-view basis. The middleware is created
with no params passed.
+ It assumes middleware that's compatible with the old style of Django 1.9
+ and earlier (having methods like ``process_request()``,
+ ``process_exception()``, and ``process_response()``).
+
.. function:: decorator_from_middleware_with_args(middleware_class)
Like ``decorator_from_middleware``, but returns a function
diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt
index b6ac9f5c89..13e5f44d5b 100644
--- a/docs/releases/1.10.txt
+++ b/docs/releases/1.10.txt
@@ -37,6 +37,17 @@ It also now includes trigram support, using the :lookup:`trigram_similar`
lookup, and the :class:`~django.contrib.postgres.search.TrigramSimilarity` and
:class:`~django.contrib.postgres.search.TrigramDistance` expressions.
+New-style middleware
+--------------------
+
+:doc:`A new style of middleware is introduced </topics/http/middleware>` to
+solve the lack of strict request/response layering of the old-style of
+middleware described in `DEP 0005
+<https://github.com/django/deps/blob/master/final/0005-improved-middleware.rst>`_.
+You'll need to :ref:`adapt old, custom middleware <upgrading-middleware>` and
+switch from the ``MIDDLEWARE_CLASSES`` setting to the new :setting:`MIDDLEWARE`
+setting to take advantage of the improvements.
+
Official support for Unicode usernames
--------------------------------------
diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt
index 3ecdcca12e..21da0dca61 100644
--- a/docs/releases/1.5.txt
+++ b/docs/releases/1.5.txt
@@ -188,8 +188,7 @@ is an iterator.
Since :class:`~django.http.StreamingHttpResponse` does not have a ``content``
attribute, middleware that needs access to the response content must test for
-streaming responses and behave accordingly. See :ref:`response-middleware` for
-more information.
+streaming responses and behave accordingly.
``{% verbatim %}`` template tag
-------------------------------
diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt
index 45526eb831..7e6794a97b 100644
--- a/docs/topics/auth/default.txt
+++ b/docs/topics/auth/default.txt
@@ -838,7 +838,7 @@ Session invalidation on password change
``SessionAuthenticationMiddleware`` is enabled. In older
versions, this protection only applies if
``django.contrib.auth.middleware.SessionAuthenticationMiddleware``
- is enabled in :setting:`MIDDLEWARE_CLASSES`.
+ is enabled in :setting:`MIDDLEWARE`.
If your :setting:`AUTH_USER_MODEL` inherits from
:class:`~django.contrib.auth.models.AbstractBaseUser` or implements its own
diff --git a/docs/topics/auth/index.txt b/docs/topics/auth/index.txt
index b57c2e7436..3224af74c7 100644
--- a/docs/topics/auth/index.txt
+++ b/docs/topics/auth/index.txt
@@ -60,7 +60,7 @@ startproject <startproject>`, these consist of two items listed in your
</ref/contrib/contenttypes>`, which allows permissions to be associated with
models you create.
-and these items in your :setting:`MIDDLEWARE_CLASSES` setting:
+and these items in your :setting:`MIDDLEWARE` setting:
1. :class:`~django.contrib.sessions.middleware.SessionMiddleware` manages
:doc:`sessions </topics/http/sessions>` across requests.
diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt
index ad353e65e0..d955b853b4 100644
--- a/docs/topics/cache.txt
+++ b/docs/topics/cache.txt
@@ -447,9 +447,9 @@ Once the cache is set up, the simplest way to use caching is to cache your
entire site. You'll need to add
``'django.middleware.cache.UpdateCacheMiddleware'`` and
``'django.middleware.cache.FetchFromCacheMiddleware'`` to your
-:setting:`MIDDLEWARE_CLASSES` setting, as in this example::
+:setting:`MIDDLEWARE` setting, as in this example::
- MIDDLEWARE_CLASSES = [
+ MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
@@ -459,7 +459,7 @@ entire site. You'll need to add
No, that's not a typo: the "update" middleware must be first in the list,
and the "fetch" middleware must be last. The details are a bit obscure, but
- see `Order of MIDDLEWARE_CLASSES`_ below if you'd like the full story.
+ see `Order of MIDDLEWARE`_ below if you'd like the full story.
Then, add the following required settings to your Django settings file:
@@ -1217,11 +1217,11 @@ Example::
def myview(request):
...
-Order of ``MIDDLEWARE_CLASSES``
-===============================
+Order of ``MIDDLEWARE``
+=======================
If you use caching middleware, it's important to put each half in the right
-place within the :setting:`MIDDLEWARE_CLASSES` setting. That's because the cache
+place within the :setting:`MIDDLEWARE` setting. That's because the cache
middleware needs to know which headers by which to vary the cache storage.
Middleware always adds something to the ``Vary`` response header when it can.
diff --git a/docs/topics/http/_images/middleware.graffle b/docs/topics/http/_images/middleware.graffle
deleted file mode 100644
index cdefd4b810..0000000000
--- a/docs/topics/http/_images/middleware.graffle
+++ /dev/null
@@ -1,957 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>ActiveLayerIndex</key>
- <integer>0</integer>
- <key>ApplicationVersion</key>
- <array>
- <string>com.omnigroup.OmniGrafflePro</string>
- <string>139.16.0.171715</string>
- </array>
- <key>AutoAdjust</key>
- <true/>
- <key>BackgroundGraphic</key>
- <dict>
- <key>Bounds</key>
- <string>{{0, 0}, {559.28997802734375, 782.8900146484375}}</string>
- <key>Class</key>
- <string>SolidGraphic</string>
- <key>ID</key>
- <integer>2</integer>
- <key>Style</key>
- <dict>
- <key>shadow</key>
- <dict>
- <key>Draws</key>
- <string>NO</string>
- </dict>
- <key>stroke</key>
- <dict>
- <key>Draws</key>
- <string>NO</string>
- </dict>
- </dict>
- </dict>
- <key>BaseZoom</key>
- <integer>0</integer>
- <key>CanvasOrigin</key>
- <string>{0, 0}</string>
- <key>ColumnAlign</key>
- <integer>1</integer>
- <key>ColumnSpacing</key>
- <real>36</real>
- <key>CreationDate</key>
- <string>2012-12-09 18:55:12 +0000</string>
- <key>Creator</key>
- <string>Aymeric Augustin</string>
- <key>DisplayScale</key>
- <string>1.000 cm = 1.000 cm</string>
- <key>GraphDocumentVersion</key>
- <integer>8</integer>
- <key>GraphicsList</key>
- <array>
- <dict>
- <key>Bounds</key>
- <string>{{144, 405}, {369, 27}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>33</integer>
- <key>Shape</key>
- <string>Bezier</string>
- <key>ShapeData</key>
- <dict>
- <key>UnitPoints</key>
- <array>
- <string>{-0.5, -0.5}</string>
- <string>{-0.5, -0.5}</string>
- <string>{0.47959183673469341, -0.5}</string>
- <string>{0.47959183673469408, -0.5}</string>
- <string>{0.47959183673469341, -0.5}</string>
- <string>{0.5, 0}</string>
- <string>{0.5, 0}</string>
- <string>{0.5, 0}</string>
- <string>{0.47959183673469408, 0.5}</string>
- <string>{0.47959183673469408, 0.5}</string>
- <string>{0.47959183673469408, 0.5}</string>
- <string>{-0.5, 0.5}</string>
- <string>{-0.5, 0.5}</string>
- <string>{-0.5, 0.5}</string>
- <string>{-0.47560975609756084, 0}</string>
- <string>{-0.47560975609756084, 0}</string>
- <string>{-0.47560975609756084, 0}</string>
- <string>{-0.5, -0.5}</string>
- </array>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
-{\colortbl;\red255\green255\blue255;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf0 view function}</string>
- </dict>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{229.5, 238.5}, {297, 36}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>31</integer>
- <key>Rotation</key>
- <real>270</real>
- <key>Shape</key>
- <string>AdjustableArrow</string>
- <key>ShapeData</key>
- <dict>
- <key>width</key>
- <real>27</real>
- </dict>
- <key>Style</key>
- <dict>
- <key>fill</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>a</key>
- <string>0.8</string>
- <key>b</key>
- <string>1</string>
- <key>g</key>
- <string>1</string>
- <key>r</key>
- <string>1</string>
- </dict>
- <key>MiddleFraction</key>
- <real>0.70634919404983521</real>
- </dict>
- <key>shadow</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>a</key>
- <string>0.4</string>
- <key>b</key>
- <string>0</string>
- <key>g</key>
- <string>0</string>
- <key>r</key>
- <string>0</string>
- </dict>
- <key>Draws</key>
- <string>NO</string>
- <key>Fuzziness</key>
- <real>0.0</real>
- <key>ShadowVector</key>
- <string>{0, 2}</string>
- </dict>
- <key>stroke</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>b</key>
- <string>0</string>
- <key>g</key>
- <string>0</string>
- <key>r</key>
- <string>1</string>
- </dict>
- <key>Pattern</key>
- <integer>1</integer>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;\red255\green0\blue0;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf2 process_exception}</string>
- </dict>
- <key>TextRelativeArea</key>
- <string>{{0.125, 0.25}, {0.75, 0.5}}</string>
- <key>isConnectedShape</key>
- <true/>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{328.5, 229.5}, {315, 36}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>30</integer>
- <key>Rotation</key>
- <real>270</real>
- <key>Shape</key>
- <string>AdjustableArrow</string>
- <key>ShapeData</key>
- <dict>
- <key>width</key>
- <real>27</real>
- </dict>
- <key>Style</key>
- <dict>
- <key>fill</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>a</key>
- <string>0.8</string>
- <key>b</key>
- <string>1</string>
- <key>g</key>
- <string>1</string>
- <key>r</key>
- <string>1</string>
- </dict>
- <key>MiddleFraction</key>
- <real>0.70634919404983521</real>
- </dict>
- <key>shadow</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>a</key>
- <string>0.4</string>
- <key>b</key>
- <string>0</string>
- <key>g</key>
- <string>0</string>
- <key>r</key>
- <string>0</string>
- </dict>
- <key>Draws</key>
- <string>NO</string>
- <key>Fuzziness</key>
- <real>0.0</real>
- <key>ShadowVector</key>
- <string>{0, 2}</string>
- </dict>
- <key>stroke</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>b</key>
- <string>0</string>
- <key>g</key>
- <string>0.501961</string>
- <key>r</key>
- <string>0</string>
- </dict>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;\red0\green128\blue0;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf2 process_response}</string>
- </dict>
- <key>TextRelativeArea</key>
- <string>{{0.125, 0.25}, {0.75, 0.5}}</string>
- <key>isConnectedShape</key>
- <true/>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{283.5, 238.5}, {297, 36}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>29</integer>
- <key>Rotation</key>
- <real>270</real>
- <key>Shape</key>
- <string>AdjustableArrow</string>
- <key>ShapeData</key>
- <dict>
- <key>width</key>
- <real>27</real>
- </dict>
- <key>Style</key>
- <dict>
- <key>fill</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>a</key>
- <string>0.8</string>
- <key>b</key>
- <string>1</string>
- <key>g</key>
- <string>1</string>
- <key>r</key>
- <string>1</string>
- </dict>
- <key>MiddleFraction</key>
- <real>0.70634919404983521</real>
- </dict>
- <key>shadow</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>a</key>
- <string>0.4</string>
- <key>b</key>
- <string>0</string>
- <key>g</key>
- <string>0</string>
- <key>r</key>
- <string>0</string>
- </dict>
- <key>Draws</key>
- <string>NO</string>
- <key>Fuzziness</key>
- <real>0.0</real>
- <key>ShadowVector</key>
- <string>{0, 2}</string>
- </dict>
- <key>stroke</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>b</key>
- <string>0</string>
- <key>g</key>
- <string>0.501961</string>
- <key>r</key>
- <string>0</string>
- </dict>
- <key>Pattern</key>
- <integer>1</integer>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;\red0\green128\blue0;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf2 process_template_response}</string>
- </dict>
- <key>TextRelativeArea</key>
- <string>{{0.125, 0.25}, {0.75, 0.5}}</string>
- <key>isConnectedShape</key>
- <true/>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{27, 243}, {288, 36}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>28</integer>
- <key>Rotation</key>
- <real>90</real>
- <key>Shape</key>
- <string>AdjustableArrow</string>
- <key>ShapeData</key>
- <dict>
- <key>width</key>
- <real>27</real>
- </dict>
- <key>Style</key>
- <dict>
- <key>fill</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>a</key>
- <string>0.8</string>
- <key>b</key>
- <string>1</string>
- <key>g</key>
- <string>1</string>
- <key>r</key>
- <string>1</string>
- </dict>
- <key>MiddleFraction</key>
- <real>0.70634919404983521</real>
- </dict>
- <key>shadow</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>a</key>
- <string>0.4</string>
- <key>b</key>
- <string>0</string>
- <key>g</key>
- <string>0</string>
- <key>r</key>
- <string>0</string>
- </dict>
- <key>Draws</key>
- <string>NO</string>
- <key>Fuzziness</key>
- <real>0.0</real>
- <key>ShadowVector</key>
- <string>{0, 2}</string>
- </dict>
- <key>stroke</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>b</key>
- <string>0</string>
- <key>g</key>
- <string>0.501961</string>
- <key>r</key>
- <string>0</string>
- </dict>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;\red0\green128\blue0;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf2 process_view}</string>
- </dict>
- <key>TextRelativeArea</key>
- <string>{{0.125, 0.25}, {0.75, 0.5}}</string>
- <key>isConnectedShape</key>
- <true/>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{-40.500000000767386, 220.49999999804004}, {297, 36}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>27</integer>
- <key>Rotation</key>
- <real>90</real>
- <key>Shape</key>
- <string>AdjustableArrow</string>
- <key>ShapeData</key>
- <dict>
- <key>width</key>
- <real>27</real>
- </dict>
- <key>Style</key>
- <dict>
- <key>fill</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>a</key>
- <string>0.8</string>
- <key>b</key>
- <string>1</string>
- <key>g</key>
- <string>1</string>
- <key>r</key>
- <string>1</string>
- </dict>
- <key>MiddleFraction</key>
- <real>0.70634919404983521</real>
- </dict>
- <key>shadow</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>a</key>
- <string>0.4</string>
- <key>b</key>
- <string>0</string>
- <key>g</key>
- <string>0</string>
- <key>r</key>
- <string>0</string>
- </dict>
- <key>Draws</key>
- <string>NO</string>
- <key>Fuzziness</key>
- <real>0.0</real>
- <key>ShadowVector</key>
- <string>{0, 2}</string>
- </dict>
- <key>stroke</key>
- <dict>
- <key>Color</key>
- <dict>
- <key>b</key>
- <string>0</string>
- <key>g</key>
- <string>0.501961</string>
- <key>r</key>
- <string>0</string>
- </dict>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;\red0\green128\blue0;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf2 process_request}</string>
- </dict>
- <key>TextRelativeArea</key>
- <string>{{0.125, 0.25}, {0.75, 0.5}}</string>
- <key>isConnectedShape</key>
- <true/>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{360, 63}, {144, 27}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>12</integer>
- <key>Magnets</key>
- <array>
- <string>{0, 1}</string>
- <string>{0, -1}</string>
- <string>{1, 0}</string>
- <string>{-1, 0}</string>
- </array>
- <key>Shape</key>
- <string>Rectangle</string>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf0 HttpResponse}</string>
- </dict>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{72, 63}, {144, 27}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>11</integer>
- <key>Magnets</key>
- <array>
- <string>{0, 1}</string>
- <string>{0, -1}</string>
- <string>{1, 0}</string>
- <string>{-1, 0}</string>
- </array>
- <key>Shape</key>
- <string>Rectangle</string>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf0 HttpRequest}</string>
- </dict>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{72, 324}, {432, 27}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>10</integer>
- <key>Magnets</key>
- <array>
- <string>{0, 1}</string>
- <string>{0, -1}</string>
- <string>{1, 0}</string>
- <string>{-1, 0}</string>
- </array>
- <key>Shape</key>
- <string>Rectangle</string>
- <key>Style</key>
- <dict>
- <key>fill</key>
- <dict>
- <key>FillType</key>
- <integer>2</integer>
- <key>GradientAngle</key>
- <real>90</real>
- <key>GradientColor</key>
- <dict>
- <key>w</key>
- <string>0.666667</string>
- </dict>
- </dict>
- <key>stroke</key>
- <dict>
- <key>CornerRadius</key>
- <real>5</real>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf0 MessageMiddleware}</string>
- </dict>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{72, 279}, {432, 27}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>9</integer>
- <key>Magnets</key>
- <array>
- <string>{0, 1}</string>
- <string>{0, -1}</string>
- <string>{1, 0}</string>
- <string>{-1, 0}</string>
- </array>
- <key>Shape</key>
- <string>Rectangle</string>
- <key>Style</key>
- <dict>
- <key>fill</key>
- <dict>
- <key>FillType</key>
- <integer>2</integer>
- <key>GradientAngle</key>
- <real>90</real>
- <key>GradientColor</key>
- <dict>
- <key>w</key>
- <string>0.666667</string>
- </dict>
- </dict>
- <key>stroke</key>
- <dict>
- <key>CornerRadius</key>
- <real>5</real>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf0 AuthenticationMiddleware}</string>
- </dict>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{72, 234}, {432, 27}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>8</integer>
- <key>Magnets</key>
- <array>
- <string>{0, 1}</string>
- <string>{0, -1}</string>
- <string>{1, 0}</string>
- <string>{-1, 0}</string>
- </array>
- <key>Shape</key>
- <string>Rectangle</string>
- <key>Style</key>
- <dict>
- <key>fill</key>
- <dict>
- <key>FillType</key>
- <integer>2</integer>
- <key>GradientAngle</key>
- <real>90</real>
- <key>GradientColor</key>
- <dict>
- <key>w</key>
- <string>0.666667</string>
- </dict>
- </dict>
- <key>stroke</key>
- <dict>
- <key>CornerRadius</key>
- <real>5</real>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf0 CsrfViewMiddleware}</string>
- </dict>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{72, 189}, {432, 27}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>7</integer>
- <key>Magnets</key>
- <array>
- <string>{0, 1}</string>
- <string>{0, -1}</string>
- <string>{1, 0}</string>
- <string>{-1, 0}</string>
- </array>
- <key>Shape</key>
- <string>Rectangle</string>
- <key>Style</key>
- <dict>
- <key>fill</key>
- <dict>
- <key>FillType</key>
- <integer>2</integer>
- <key>GradientAngle</key>
- <real>90</real>
- <key>GradientColor</key>
- <dict>
- <key>w</key>
- <string>0.666667</string>
- </dict>
- </dict>
- <key>stroke</key>
- <dict>
- <key>CornerRadius</key>
- <real>5</real>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf0 SessionMiddleware}</string>
- </dict>
- </dict>
- <dict>
- <key>Bounds</key>
- <string>{{72, 144}, {432, 27}}</string>
- <key>Class</key>
- <string>ShapedGraphic</string>
- <key>ID</key>
- <integer>6</integer>
- <key>Magnets</key>
- <array>
- <string>{0, 1}</string>
- <string>{0, -1}</string>
- <string>{1, 0}</string>
- <string>{-1, 0}</string>
- </array>
- <key>Shape</key>
- <string>Rectangle</string>
- <key>Style</key>
- <dict>
- <key>fill</key>
- <dict>
- <key>FillType</key>
- <integer>2</integer>
- <key>GradientAngle</key>
- <real>90</real>
- <key>GradientColor</key>
- <dict>
- <key>w</key>
- <string>0.666667</string>
- </dict>
- </dict>
- <key>stroke</key>
- <dict>
- <key>CornerRadius</key>
- <real>5</real>
- </dict>
- </dict>
- <key>Text</key>
- <dict>
- <key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
-\cocoascreenfonts1{\fonttbl\f0\fmodern\fcharset0 Courier;}
-{\colortbl;\red255\green255\blue255;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
-
-\f0\fs24 \cf0 CommonMiddleware}</string>
- </dict>
- </dict>
- </array>
- <key>GridInfo</key>
- <dict>
- <key>ShowsGrid</key>
- <string>YES</string>
- <key>SnapsToGrid</key>
- <string>YES</string>
- </dict>
- <key>GuidesLocked</key>
- <string>NO</string>
- <key>GuidesVisible</key>
- <string>YES</string>
- <key>HPages</key>
- <integer>1</integer>
- <key>ImageCounter</key>
- <integer>1</integer>
- <key>KeepToScale</key>
- <false/>
- <key>Layers</key>
- <array>
- <dict>
- <key>Lock</key>
- <string>NO</string>
- <key>Name</key>
- <string>Calque 1</string>
- <key>Print</key>
- <string>YES</string>
- <key>View</key>
- <string>YES</string>
- </dict>
- </array>
- <key>LayoutInfo</key>
- <dict>
- <key>Animate</key>
- <string>NO</string>
- <key>circoMinDist</key>
- <real>18</real>
- <key>circoSeparation</key>
- <real>0.0</real>
- <key>layoutEngine</key>
- <string>dot</string>
- <key>neatoSeparation</key>
- <real>0.0</real>
- <key>twopiSeparation</key>
- <real>0.0</real>
- </dict>
- <key>LinksVisible</key>
- <string>NO</string>
- <key>MagnetsVisible</key>
- <string>NO</string>
- <key>MasterSheets</key>
- <array/>
- <key>ModificationDate</key>
- <string>2012-12-09 19:48:54 +0000</string>
- <key>Modifier</key>
- <string>Aymeric Augustin</string>
- <key>NotesVisible</key>
- <string>NO</string>
- <key>Orientation</key>
- <integer>2</integer>
- <key>OriginVisible</key>
- <string>NO</string>
- <key>PageBreaks</key>
- <string>YES</string>
- <key>PrintInfo</key>
- <dict>
- <key>NSBottomMargin</key>
- <array>
- <string>float</string>
- <string>41</string>
- </array>
- <key>NSHorizonalPagination</key>
- <array>
- <string>coded</string>
- <string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG</string>
- </array>
- <key>NSLeftMargin</key>
- <array>
- <string>float</string>
- <string>18</string>
- </array>
- <key>NSPaperSize</key>
- <array>
- <string>size</string>
- <string>{595.28997802734375, 841.8900146484375}</string>
- </array>
- <key>NSPrintReverseOrientation</key>
- <array>
- <string>int</string>
- <string>0</string>
- </array>
- <key>NSRightMargin</key>
- <array>
- <string>float</string>
- <string>18</string>
- </array>
- <key>NSTopMargin</key>
- <array>
- <string>float</string>
- <string>18</string>
- </array>
- </dict>
- <key>PrintOnePage</key>
- <false/>
- <key>ReadOnly</key>
- <string>NO</string>
- <key>RowAlign</key>
- <integer>1</integer>
- <key>RowSpacing</key>
- <real>36</real>
- <key>SheetTitle</key>
- <string>Canevas 1</string>
- <key>SmartAlignmentGuidesActive</key>
- <string>YES</string>
- <key>SmartDistanceGuidesActive</key>
- <string>YES</string>
- <key>UniqueID</key>
- <integer>1</integer>
- <key>UseEntirePage</key>
- <false/>
- <key>VPages</key>
- <integer>1</integer>
- <key>WindowInfo</key>
- <dict>
- <key>CurrentSheet</key>
- <integer>0</integer>
- <key>ExpandedCanvases</key>
- <array/>
- <key>Frame</key>
- <string>{{248, 4}, {694, 874}}</string>
- <key>ListView</key>
- <true/>
- <key>OutlineWidth</key>
- <integer>142</integer>
- <key>RightSidebar</key>
- <false/>
- <key>ShowRuler</key>
- <true/>
- <key>Sidebar</key>
- <true/>
- <key>SidebarWidth</key>
- <integer>120</integer>
- <key>VisibleRegion</key>
- <string>{{0, 0}, {559, 735}}</string>
- <key>Zoom</key>
- <real>1</real>
- <key>ZoomValues</key>
- <array>
- <array>
- <string>Canevas 1</string>
- <real>1</real>
- <real>1</real>
- </array>
- </array>
- </dict>
-</dict>
-</plist>
diff --git a/docs/topics/http/_images/middleware.svg b/docs/topics/http/_images/middleware.svg
deleted file mode 100644
index 4da8d22da8..0000000000
--- a/docs/topics/http/_images/middleware.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="52 47 481 409" width="481pt" height="409pt"><metadata xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:date>2012-12-09 19:48Z</dc:date><!-- Produced by OmniGraffle Professional 5.4.2 --></metadata><defs><filter id="Shadow" filterUnits="userSpaceOnUse"><feGaussianBlur in="SourceAlpha" result="blur" stdDeviation="3.488"/><feOffset in="blur" result="offset" dx="0" dy="4"/><feFlood flood-color="black" flood-opacity=".75" result="flood"/><feComposite in="flood" in2="offset" operator="in"/></filter><linearGradient x1="0" x2="1" id="Gradient" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="white"/><stop offset="1" stop-color="#aaa"/></linearGradient><linearGradient id="Obj_Gradient" xl:href="#Gradient" gradientTransform="translate(288 144) rotate(90) scale(27)"/><font-face font-family="Courier" font-size="12" units-per-em="1000" underline-position="-178.22266" underline-thickness="57.617188" slope="0" x-height="462.40234" cap-height="594.72656" ascent="753.90625" descent="-246.09375" font-weight="500"><font-face-src><font-face-name name="Courier"/></font-face-src></font-face><linearGradient id="Obj_Gradient_2" xl:href="#Gradient" gradientTransform="translate(288 189) rotate(90) scale(27)"/><linearGradient id="Obj_Gradient_3" xl:href="#Gradient" gradientTransform="translate(288 234) rotate(90) scale(27)"/><linearGradient id="Obj_Gradient_4" xl:href="#Gradient" gradientTransform="translate(288 279) rotate(90) scale(27)"/><linearGradient id="Obj_Gradient_5" xl:href="#Gradient" gradientTransform="translate(288 324) rotate(90) scale(27)"/><font-face font-family="Helvetica" font-size="12" units-per-em="1000" underline-position="-75.683594" underline-thickness="49.316406" slope="0" x-height="522.94922" cap-height="717.28516" ascent="770.01953" descent="-229.98047" font-weight="500"><font-face-src><font-face-name name="Helvetica"/></font-face-src></font-face></defs><g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1"><title>Canevas 1</title><rect fill="white" width="559.28998" height="782.89"/><g><title>Calque 1</title><g><use xl:href="#id6_Graphic" filter="url(#Shadow)"/><use xl:href="#id7_Graphic" filter="url(#Shadow)"/><use xl:href="#id8_Graphic" filter="url(#Shadow)"/><use xl:href="#id9_Graphic" filter="url(#Shadow)"/><use xl:href="#id10_Graphic" filter="url(#Shadow)"/><use xl:href="#id11_Graphic" filter="url(#Shadow)"/><use xl:href="#id12_Graphic" filter="url(#Shadow)"/><use xl:href="#id33_Graphic" filter="url(#Shadow)"/></g><g id="id6_Graphic"><path d="M 77 144 L 499 144 C 501.76142 144 504 146.23858 504 149 L 504 166 C 504 168.76142 501.76142 171 499 171 L 77 171 C 74.238576 171 72 168.76142 72 166 C 72 166 72 166 72 166 L 72 149 C 72 146.23858 74.238576 144 77 144 C 77 144 77 144 77 144 Z" fill="url(#Obj_Gradient)"/><path d="M 77 144 L 499 144 C 501.76142 144 504 146.23858 504 149 L 504 166 C 504 168.76142 501.76142 171 499 171 L 77 171 C 74.238576 171 72 168.76142 72 166 C 72 166 72 166 72 166 L 72 149 C 72 146.23858 74.238576 144 77 144 C 77 144 77 144 77 144 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(77 150.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" fill="black" x="153.390625" y="11" textLength="115.21875">CommonMiddleware</tspan></text></g><g id="id7_Graphic"><path d="M 77 189 L 499 189 C 501.76142 189 504 191.23858 504 194 L 504 211 C 504 213.76142 501.76142 216 499 216 L 77 216 C 74.238576 216 72 213.76142 72 211 C 72 211 72 211 72 211 L 72 194 C 72 191.23858 74.238576 189 77 189 C 77 189 77 189 77 189 Z" fill="url(#Obj_Gradient_2)"/><path d="M 77 189 L 499 189 C 501.76142 189 504 191.23858 504 194 L 504 211 C 504 213.76142 501.76142 216 499 216 L 77 216 C 74.238576 216 72 213.76142 72 211 C 72 211 72 211 72 211 L 72 194 C 72 191.23858 74.238576 189 77 189 C 77 189 77 189 77 189 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(77 195.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="149.79004" y="11" textLength="122.41992">SessionMiddleware</tspan></text></g><g id="id8_Graphic"><path d="M 77 234 L 499 234 C 501.76142 234 504 236.23858 504 239 L 504 256 C 504 258.76142 501.76142 261 499 261 L 77 261 C 74.238576 261 72 258.76142 72 256 C 72 256 72 256 72 256 L 72 239 C 72 236.23858 74.238576 234 77 234 C 77 234 77 234 77 234 Z" fill="url(#Obj_Gradient_3)"/><path d="M 77 234 L 499 234 C 501.76142 234 504 236.23858 504 239 L 504 256 C 504 258.76142 501.76142 261 499 261 L 77 261 C 74.238576 261 72 258.76142 72 256 C 72 256 72 256 72 256 L 72 239 C 72 236.23858 74.238576 234 77 234 C 77 234 77 234 77 234 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(77 240.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="146.18945" y="11" textLength="129.62109">CsrfViewMiddleware</tspan></text></g><g id="id9_Graphic"><path d="M 77 279 L 499 279 C 501.76142 279 504 281.23858 504 284 L 504 301 C 504 303.76142 501.76142 306 499 306 L 77 306 C 74.238576 306 72 303.76142 72 301 C 72 301 72 301 72 301 L 72 284 C 72 281.23858 74.238576 279 77 279 C 77 279 77 279 77 279 Z" fill="url(#Obj_Gradient_4)"/><path d="M 77 279 L 499 279 C 501.76142 279 504 281.23858 504 284 L 504 301 C 504 303.76142 501.76142 306 499 306 L 77 306 C 74.238576 306 72 303.76142 72 301 C 72 301 72 301 72 301 L 72 284 C 72 281.23858 74.238576 279 77 279 C 77 279 77 279 77 279 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(77 285.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="124.58594" y="11" textLength="172.82812">AuthenticationMiddleware</tspan></text></g><g id="id10_Graphic"><path d="M 77 324 L 499 324 C 501.76142 324 504 326.23858 504 329 L 504 346 C 504 348.76142 501.76142 351 499 351 L 77 351 C 74.238576 351 72 348.76142 72 346 C 72 346 72 346 72 346 L 72 329 C 72 326.23858 74.238576 324 77 324 C 77 324 77 324 77 324 Z" fill="url(#Obj_Gradient_5)"/><path d="M 77 324 L 499 324 C 501.76142 324 504 326.23858 504 329 L 504 346 C 504 348.76142 501.76142 351 499 351 L 77 351 C 74.238576 351 72 348.76142 72 346 C 72 346 72 346 72 346 L 72 329 C 72 326.23858 74.238576 324 77 324 C 77 324 77 324 77 324 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(77 330.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="149.79004" y="11" textLength="122.41992">MessageMiddleware</tspan></text></g><g id="id11_Graphic"><rect x="72" y="63" width="144" height="27" fill="white"/><rect x="72" y="63" width="144" height="27" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(77 69.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="27.393555" y="11" textLength="79.21289">HttpRequest</tspan></text></g><g id="id12_Graphic"><rect x="360" y="63" width="144" height="27" fill="white"/><rect x="360" y="63" width="144" height="27" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(365 69.5)" fill="black"><tspan font-family="Courier" font-size="12" font-weight="500" x="23.792969" y="11" textLength="86.41406">HttpResponse</tspan></text></g><path d="M 99 90 L 117 90 L 117 360 L 126 360 L 108 387 L 90 360 L 99 360 Z" fill="white" fill-opacity=".8"/><path d="M 99 90 L 117 90 L 117 360 L 126 360 L 108 387 L 90 360 L 99 360 Z" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(115 132.125) rotate(90)" fill="green"><tspan font-family="Courier" font-size="12" font-weight="500" fill="green" x="52.36621" y="11" textLength="108.01758">process_request</tspan></text><path d="M 162 117 L 180 117 L 180 378 L 189 378 L 171 405 L 153 378 L 162 378 Z" fill="white" fill-opacity=".8"/><path d="M 162 117 L 180 117 L 180 378 L 189 378 L 171 405 L 153 378 L 162 378 Z" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(178 158) rotate(90)" fill="green"><tspan font-family="Courier" font-size="12" font-weight="500" fill="green" x="59.79297" y="11" textLength="86.41406">process_view</tspan></text><path d="M 441 405 L 423 405 L 423 135 L 414 135 L 432 108 L 450 135 L 441 135 Z" fill="white" fill-opacity=".8"/><path d="M 441 405 L 423 405 L 423 135 L 414 135 L 432 108 L 450 135 L 441 135 Z" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/><text transform="translate(425 362.875) rotate(-90)" fill="green"><tspan font-family="Courier" font-size="12" font-weight="500" fill="green" x="16.360352" y="11" textLength="180.0293">process_template_response</tspan></text><path d="M 495 405 L 477 405 L 477 117 L 468 117 L 486 90 L 504 117 L 495 117 Z" fill="white" fill-opacity=".8"/><path d="M 495 405 L 477 405 L 477 117 L 468 117 L 486 90 L 504 117 L 495 117 Z" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(479 360.625) rotate(-90)" fill="green"><tspan font-family="Courier" font-size="12" font-weight="500" fill="green" x="55.515625" y="11" textLength="115.21875">process_response</tspan></text><path d="M 387 405 L 369 405 L 369 135 L 360 135 L 378 108 L 396 135 L 387 135 Z" fill="white" fill-opacity=".8"/><path d="M 387 405 L 369 405 L 369 135 L 360 135 L 378 108 L 396 135 L 387 135 Z" stroke="red" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/><text transform="translate(371 362.875) rotate(-90)" fill="red"><tspan font-family="Courier" font-size="12" font-weight="500" fill="red" x="45.16504" y="11" textLength="122.41992">process_exception</tspan></text><g id="id33_Graphic"><path d="M 144 405 L 505.4694 405 L 513 418.5 L 505.4694 432 L 144 432 L 153 418.5 Z" fill="white"/><path d="M 144 405 L 505.4694 405 L 513 418.5 L 505.4694 432 L 144 432 L 153 418.5 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(149 411.5)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" fill="black" x="144.81543" y="11" textLength="69.36914">view function</tspan></text></g></g></g></svg>
diff --git a/docs/topics/http/middleware.txt b/docs/topics/http/middleware.txt
index 16fdace825..1f5414e95b 100644
--- a/docs/topics/http/middleware.txt
+++ b/docs/topics/http/middleware.txt
@@ -16,18 +16,128 @@ how to write your own middleware. Django ships with some built-in middleware
you can use right out of the box. They're documented in the :doc:`built-in
middleware reference </ref/middleware>`.
+.. versionchanged:: 1.10
+
+ A new style of middleware was introduced for use with the new
+ :setting:`MIDDLEWARE` setting. If you're using the old
+ :setting:`MIDDLEWARE_CLASSES` setting, you'll need to :ref:`adapt old,
+ custom middleware <upgrading-middleware>` before using the new setting.
+ This document describes new-style middleware. Refer to this page in older
+ versions of the documentation for a description of how old-style middleware
+ works.
+
+Writing your own middleware
+===========================
+
+A middleware factory is a callable that takes a ``get_response`` callable and
+returns a middleware. A middleware is a callable that takes a request and
+returns a response, just like a view.
+
+A middleware can be written as a function that looks like this::
+
+ def simple_middleware(get_response):
+ # One-time configuration and initialization.
+
+ def middleware(request):
+ # Code to be executed for each request before
+ # the view is called.
+
+ try:
+ response = get_response(request)
+ except Exception as e:
+ # Code to handle an exception that wasn't caught
+ # further up the chain, if desired.
+ ...
+
+ # Code to be executed for each request/response after
+ # the view is called.
+
+ return response
+
+ return middleware
+
+Or it can be written as a class with a ``__call__()`` method, like this::
+
+ class SimpleMiddleware(object):
+ def __init__(self, get_response):
+ self.get_response = get_response
+ # One-time configuration and initialization.
+
+ def __call__(self, request):
+ # Code to be executed for each request before
+ # the view is called.
+
+ try:
+ response = self.get_response(request)
+ except Exception as e:
+ # Code to handle an exception that wasn't caught
+ # further up the chain, if desired.
+ ...
+
+ # Code to be executed for each request/response after
+ # the view is called.
+
+ return response
+
+In both examples, the ``try``/``except`` isn't required if the middleware
+doesn't need to handle any exceptions. If it is included, it should probably
+catch something more specific than ``Exception``.
+
+The ``get_response`` callable provided by Django might be the actual view (if
+this is the last listed middleware) or it might be the next middleware in the
+chain. The current middleware doesn't need to know or care what exactly it is,
+just that it represents whatever comes next.
+
+The above is a slight simplification -- the ``get_response`` callable for the
+last middleware in the chain won't be the actual view but rather a wrapper
+method from the handler which takes care of applying :ref:`view middleware
+<view-middleware>`, calling the view with appropriate URL arguments, and
+applying :ref:`template-response <template-response-middleware>` middleware.
+
+Middleware can live anywhere on your Python path.
+
+``__init__(get_response)``
+--------------------------
+
+Middleware classes must accept a ``get_response`` argument. You can also
+initialize some global state for the middleware. Keep in mind a couple of
+caveats:
+
+* Django initializes your middleware with only the ``get_response`` argument,
+ so you can't define ``__init__()`` as requiring any other arguments.
+
+* Unlike the ``__call__()`` method which get called once per request,
+ ``__init__()`` is called only *once*, when the Web server starts.
+
+.. versionchanged:: 1.10
+
+ In older versions, ``__init__`` was not called until the Web server
+ responded to its first request.
+
+ If you want to allow your middleware to be used in Django 1.9 and earlier,
+ make ``get_response`` an optional argument (``get_response=None``).
+
+Marking middleware as unused
+----------------------------
+
+It's sometimes useful to determine at startup time whether a piece of
+middleware should be used. In these cases, your middleware's ``__init__()``
+method may raise :exc:`~django.core.exceptions.MiddlewareNotUsed`. Django will
+then remove that middleware from the middleware process and log a debug message
+to the :ref:`django-request-logger` logger when :setting:`DEBUG` is ``True``.
+
Activating middleware
=====================
-To activate a middleware component, add it to the
-:setting:`MIDDLEWARE_CLASSES` list in your Django settings.
+To activate a middleware component, add it to the :setting:`MIDDLEWARE` list in
+your Django settings.
-In :setting:`MIDDLEWARE_CLASSES`, each middleware component is represented by
-a string: the full Python path to the middleware's class name. For example,
+In :setting:`MIDDLEWARE`, each middleware component is represented by a string:
+the full Python path to the middleware's class or function name. For example,
here's the default value created by :djadmin:`django-admin startproject
<startproject>`::
- MIDDLEWARE_CLASSES = [
+ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
@@ -37,13 +147,12 @@ here's the default value created by :djadmin:`django-admin startproject
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
-A Django installation doesn't require any middleware —
-:setting:`MIDDLEWARE_CLASSES` can be empty, if you'd like — but it's strongly
-suggested that you at least use
+A Django installation doesn't require any middleware — :setting:`MIDDLEWARE`
+can be empty, if you'd like — but it's strongly suggested that you at least use
:class:`~django.middleware.common.CommonMiddleware`.
-The order in :setting:`MIDDLEWARE_CLASSES` matters because a middleware can
-depend on other middleware. For instance,
+The order in :setting:`MIDDLEWARE` matters because a middleware can depend on
+other middleware. For instance,
:class:`~django.contrib.auth.middleware.AuthenticationMiddleware` stores the
authenticated user in the session; therefore, it must run after
:class:`~django.contrib.sessions.middleware.SessionMiddleware`. See
@@ -54,55 +163,21 @@ Hooks and application order
===========================
During the request phase, before calling the view, Django applies middleware
-in the order it's defined in :setting:`MIDDLEWARE_CLASSES`, top-down. Two
-hooks are available:
-
-* :meth:`process_request`
-* :meth:`process_view`
-
-During the response phase, after calling the view, middleware are applied in
-reverse order, from the bottom up. Three hooks are available:
-
-* :meth:`process_exception` (only if the view raised an exception)
-* :meth:`process_template_response` (only for template responses)
-* :meth:`process_response`
+in the order it's defined in :setting:`MIDDLEWARE`, top-down. You can think of
+it like an onion: each middleware class is a "layer" that wraps the view.
-.. image:: _images/middleware.*
- :alt: middleware application order
- :width: 481
- :height: 409
+Middleware see only the changes made by middleware that run before it. A
+middleware (and the view) is skipped entirely if a preceding middleware
+short-circuits by returning a response without ever calling ``get_response``.
+That response will only pass through the middleware that have already run.
-If you prefer, you can also think of it like an onion: each middleware class
-is a "layer" that wraps the view.
-
-The behavior of each hook is described below.
-
-Writing your own middleware
-===========================
+Similarly, a middleware that sees the request on the way in and doesn't return
+a response is guaranteed that it will always see the response on the way back
+out. If the middleware also wants to see any uncaught exception on the way out,
+it can wrap its call to ``get_response()`` in a ``try``/``except``.
-Writing your own middleware is easy. Each middleware component is a single
-Python class that defines one or more of the following methods:
-
-.. _request-middleware:
-
-``process_request()``
----------------------
-
-.. method:: process_request(request)
-
-``request`` is an :class:`~django.http.HttpRequest` object.
-
-``process_request()`` is called on each request, before Django decides which
-view to execute.
-
-It should return either ``None`` or an :class:`~django.http.HttpResponse`
-object. If it returns ``None``, Django will continue processing this request,
-executing any other ``process_request()`` middleware, then, ``process_view()``
-middleware, and finally, the appropriate view. If it returns an
-:class:`~django.http.HttpResponse` object, Django won't bother calling any
-other request, view or exception middleware, or the appropriate view; it'll
-apply response middleware to that :class:`~django.http.HttpResponse`, and
-return the result.
+Besides the middleware pattern described earlier, you can add two other methods
+to class-based middleware:
.. _view-middleware:
@@ -125,14 +200,13 @@ It should return either ``None`` or an :class:`~django.http.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 :class:`~django.http.HttpResponse` object, Django won't
-bother calling any other view or exception middleware, or the appropriate
-view; it'll apply response middleware to that
-:class:`~django.http.HttpResponse`, and return the result.
+bother calling the appropriate view; it'll apply response middleware to that
+:class:`~django.http.HttpResponse` and return the result.
.. note::
Accessing :attr:`request.POST <django.http.HttpRequest.POST>` inside
- middleware from ``process_request`` or ``process_view`` will prevent any
+ middleware before the view runs or in ``process_view()`` will prevent any
view running after the middleware from being able to :ref:`modify the
upload handlers for the request <modifying_upload_handlers_on_the_fly>`,
and should normally be avoided.
@@ -170,41 +244,8 @@ called.
Middleware are run in reverse order during the response phase, which
includes ``process_template_response()``.
-.. _response-middleware:
-
-``process_response()``
-----------------------
-
-.. method:: process_response(request, response)
-
-``request`` is an :class:`~django.http.HttpRequest` object. ``response`` is
-the :class:`~django.http.HttpResponse` or
-:class:`~django.http.StreamingHttpResponse` object returned by a Django view
-or by a middleware.
-
-``process_response()`` is called on all responses before they're returned to
-the browser.
-
-It must return an :class:`~django.http.HttpResponse` or
-:class:`~django.http.StreamingHttpResponse` object. It could alter the given
-``response``, or it could create and return a brand-new
-:class:`~django.http.HttpResponse` or
-:class:`~django.http.StreamingHttpResponse`.
-
-Unlike the ``process_request()`` and ``process_view()`` methods, the
-``process_response()`` method is always called, even if the
-``process_request()`` and ``process_view()`` methods of the same middleware
-class were skipped (because an earlier middleware method returned an
-:class:`~django.http.HttpResponse`). In particular, this means that your
-``process_response()`` method cannot rely on setup done in
-``process_request()``.
-
-Finally, remember that during the response phase, middleware are applied in
-reverse order, from the bottom up. This means classes defined at the end of
-:setting:`MIDDLEWARE_CLASSES` will be run first.
-
Dealing with streaming responses
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+================================
Unlike :class:`~django.http.HttpResponse`,
:class:`~django.http.StreamingHttpResponse` does not have a ``content``
@@ -229,66 +270,62 @@ must test for streaming responses and adjust their behavior accordingly::
.. _exception-middleware:
-``process_exception()``
------------------------
+Exception middleware
+====================
-.. method:: process_exception(request, exception)
+A middleware that does some custom exception handling might looks like this::
-``request`` is an :class:`~django.http.HttpRequest` object. ``exception`` is an
-``Exception`` object raised by the view function.
+ class ExceptionMiddleware(object):
+ def __init__(self, get_response):
+ self.get_response = get_response
-Django calls ``process_exception()`` when a view raises an exception.
-``process_exception()`` should return either ``None`` or an
-:class:`~django.http.HttpResponse` object. If it returns an
-:class:`~django.http.HttpResponse` object, the template response and response
-middleware will be applied, and the resulting response returned to the
-browser. Otherwise, default exception handling kicks in.
+ def __call__(self, request):
+ try:
+ response = self.get_response(request)
+ except Exception as e:
+ # Do something with the exception and possibly reraise it
+ # unless you wish to silence it.
+ ...
+ return response
-Again, middleware are run in reverse order during the response phase, which
-includes ``process_exception``. If an exception middleware returns a response,
-the middleware classes above that middleware will not be called at all.
+Middleware that wants to do something for all exception responses, an HTTP 404
+for example, need to both catch the appropriate exception (e.g. ``Http404``)
+and look for regular responses with the status code of interest. You can
+subclass :class:`~django.middleware.exception.ExceptionMiddleware` if you want
+to transform exceptions into the appropriate response.
-``__init__()``
---------------
+.. _upgrading-middleware:
-Most middleware classes won't need an initializer since middleware classes are
-essentially placeholders for the ``process_*`` methods. If you do need some
-global state you may use ``__init__`` to set up. However, keep in mind a couple
-of caveats:
+Upgrading pre-Django 1.10-style middleware
+==========================================
-* Django initializes your middleware without any arguments, so you can't
- define ``__init__`` as requiring any arguments.
-
-* Unlike the ``process_*`` methods which get called once per request,
- ``__init__`` gets called only *once*, when the Web server starts.
-
-.. versionchanged:: 1.10
-
- In older versions, ``__init__`` was not called until the Web server
- responded to its first request.
-
-Marking middleware as unused
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. class:: django.utils.deprecation.MiddlewareMixin
+ :module:
-It's sometimes useful to determine at run-time whether a piece of middleware
-should be used. In these cases, your middleware's ``__init__`` method may
-raise :exc:`django.core.exceptions.MiddlewareNotUsed`. Django will then remove
-that piece of middleware from the middleware process and a debug message will
-be logged to the ``django.request`` logger when :setting:`DEBUG` is set to
-``True``.
+Django provides ``django.utils.deprecation.MiddlewareMixin`` to ease providing
+the existing built-in middleware in both new-style and old-style forms and to
+ease similar conversions of third-party middleware.
-Guidelines
-----------
+In most cases, this mixin will be sufficient to convert a middleware with
+sufficient backwards-compatibility; the new short-circuiting semantics will be
+harmless or even beneficial to the existing middleware.
-* Middleware classes don't have to subclass anything.
+In a few cases, a middleware class may need more invasive changes to adjust to
+the new semantics.
-* The middleware class can live anywhere on your Python path. All Django
- cares about is that the :setting:`MIDDLEWARE_CLASSES` setting includes
- the path to it.
+For example, in the current request-handling logic, the handler transforms any
+exception that passes through all ``process_exception`` middleware uncaught
+into a response with appropriate status code (e.g. 404, 403, 400, or 500), and
+then passes that response through the full chain of ``process_response``
+middleware.
-* Feel free to look at :doc:`Django's available middleware
- </ref/middleware>` for examples.
+In new-style middleware, a given middleware only gets one shot at a given
+response or uncaught exception "on the way out," and will see either a returned
+response or an uncaught exception, but not both.
-* If you write a middleware component that you think would be useful to
- other people, contribute to the community! :doc:`Let us know
- </internals/contributing/index>`, and we'll consider adding it to Django.
+This means that certain middleware which want to do something with all 404
+responses (for example, the ``RedirectFallbackMiddleware`` and
+``FlatpageFallbackMiddleware`` in ``django.contrib.redirects`` and
+``django.contrib.flatpages``) now need to watch out for both a 404 response
+and an uncaught ``Http404`` exception. They do this by subclassing
+:class:`~django.middleware.exception.ExceptionMiddleware`.
diff --git a/docs/topics/http/sessions.txt b/docs/topics/http/sessions.txt
index 34a1b28b73..1a948397ae 100644
--- a/docs/topics/http/sessions.txt
+++ b/docs/topics/http/sessions.txt
@@ -18,13 +18,13 @@ Sessions are implemented via a piece of :doc:`middleware </ref/middleware>`.
To enable session functionality, do the following:
-* Edit the :setting:`MIDDLEWARE_CLASSES` setting and make sure
- it contains ``'django.contrib.sessions.middleware.SessionMiddleware'``.
- The default ``settings.py`` created by ``django-admin startproject``
- has ``SessionMiddleware`` activated.
+* Edit the :setting:`MIDDLEWARE` setting and make sure it contains
+ ``'django.contrib.sessions.middleware.SessionMiddleware'``. The default
+ ``settings.py`` created by ``django-admin startproject`` has
+ ``SessionMiddleware`` activated.
If you don't want to use sessions, you might as well remove the
-``SessionMiddleware`` line from :setting:`MIDDLEWARE_CLASSES` and
+``SessionMiddleware`` line from :setting:`MIDDLEWARE` and
``'django.contrib.sessions'`` from your :setting:`INSTALLED_APPS`.
It'll save you a small bit of overhead.
diff --git a/docs/topics/http/urls.txt b/docs/topics/http/urls.txt
index 81dc4a0d94..ae5b714726 100644
--- a/docs/topics/http/urls.txt
+++ b/docs/topics/http/urls.txt
@@ -41,8 +41,8 @@ algorithm the system follows to determine which Python code to execute:
1. Django determines the root URLconf module to use. Ordinarily,
this is the value of the :setting:`ROOT_URLCONF` setting, but if the incoming
``HttpRequest`` object has a :attr:`~django.http.HttpRequest.urlconf`
- attribute (set by middleware :ref:`request processing <request-middleware>`),
- its value will be used in place of the :setting:`ROOT_URLCONF` setting.
+ attribute (set by middleware), its value will be used in place of the
+ :setting:`ROOT_URLCONF` setting.
2. Django loads that Python module and looks for the variable
``urlpatterns``. This should be a Python list of :func:`django.conf.urls.url`
diff --git a/docs/topics/i18n/timezones.txt b/docs/topics/i18n/timezones.txt
index 8ea63f2908..674edc1a19 100644
--- a/docs/topics/i18n/timezones.txt
+++ b/docs/topics/i18n/timezones.txt
@@ -175,13 +175,14 @@ the most likely choices.
Here's an example that stores the current timezone in the session. (It skips
error handling entirely for the sake of simplicity.)
-Add the following middleware to :setting:`MIDDLEWARE_CLASSES`::
+Add the following middleware to :setting:`MIDDLEWARE`::
import pytz
from django.utils import timezone
+ from django.django.utils.deprecation import MiddlewareMixin
- class TimezoneMiddleware(object):
+ class TimezoneMiddleware(MiddlewareMixin):
def process_request(self, request):
tzname = request.session.get('django_timezone')
if tzname:
diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt
index 43184a13a1..3f13021bc8 100644
--- a/docs/topics/i18n/translation.txt
+++ b/docs/topics/i18n/translation.txt
@@ -38,7 +38,7 @@ make some optimizations so as not to load the internationalization machinery.
.. note::
Make sure you've activated translation for your project (the fastest way is
- to check if :setting:`MIDDLEWARE_CLASSES` includes
+ to check if :setting:`MIDDLEWARE` includes
:mod:`django.middleware.locale.LocaleMiddleware`). If you haven't yet,
see :ref:`how-django-discovers-language-preference`.
@@ -1422,7 +1422,7 @@ Django provides two mechanisms to internationalize URL patterns:
Using either one of these features requires that an active language be set
for each request; in other words, you need to have
:class:`django.middleware.locale.LocaleMiddleware` in your
- :setting:`MIDDLEWARE_CLASSES` setting.
+ :setting:`MIDDLEWARE` setting.
Language prefix in URL patterns
-------------------------------
@@ -2065,8 +2065,8 @@ prefer, then you also need to use the ``LocaleMiddleware``.
It customizes content for each user.
To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'``
-to your :setting:`MIDDLEWARE_CLASSES` setting. Because middleware order
-matters, you should follow these guidelines:
+to your :setting:`MIDDLEWARE` setting. Because middleware order matters, follow
+these guidelines:
* Make sure it's one of the first middlewares installed.
* It should come after ``SessionMiddleware``, because ``LocaleMiddleware``
@@ -2075,9 +2075,9 @@ matters, you should follow these guidelines:
to resolve the requested URL.
* If you use ``CacheMiddleware``, put ``LocaleMiddleware`` after it.
-For example, your :setting:`MIDDLEWARE_CLASSES` might look like this::
+For example, your :setting:`MIDDLEWARE` might look like this::
- MIDDLEWARE_CLASSES = [
+ MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt
index 8db06c15a3..d2ef214c36 100644
--- a/docs/topics/testing/tools.txt
+++ b/docs/topics/testing/tools.txt
@@ -1182,7 +1182,7 @@ easy::
class MiddlewareTestCase(TestCase):
def test_cache_middleware(self):
- with self.modify_settings(MIDDLEWARE_CLASSES={
+ with self.modify_settings(MIDDLEWARE={
'append': 'django.middleware.cache.FetchFromCacheMiddleware',
'prepend': 'django.middleware.cache.UpdateCacheMiddleware',
'remove': [
@@ -1233,7 +1233,7 @@ decorator::
class MiddlewareTestCase(TestCase):
- @modify_settings(MIDDLEWARE_CLASSES={
+ @modify_settings(MIDDLEWARE={
'append': 'django.middleware.cache.FetchFromCacheMiddleware',
'prepend': 'django.middleware.cache.UpdateCacheMiddleware',
})
@@ -1245,7 +1245,7 @@ The decorator can also be applied to test case classes::
from django.test import TestCase, modify_settings
- @modify_settings(MIDDLEWARE_CLASSES={
+ @modify_settings(MIDDLEWARE={
'append': 'django.middleware.cache.FetchFromCacheMiddleware',
'prepend': 'django.middleware.cache.UpdateCacheMiddleware',
})