@@ -4,25 +4,28 @@ Middleware
44
55Middleware is a framework of hooks into Django's request/response processing.
66It's a light, low-level "plugin" system for globally altering Django's input
7- and/ or output.
7+ or output.
88
99Each middleware component is responsible for doing some specific function. For
10- example, Django includes a middleware component, ``XViewMiddleware``, that adds
11- an ``"X-View"`` HTTP header to every response to a ``HEAD`` request.
10+ example, Django includes a middleware component,
11+ :class:`~django.middleware.transaction.TransactionMiddleware`, that wraps the
12+ processing of each HTTP request in a database transaction.
1213
1314This document explains how middleware works, how you activate middleware, and
1415how to write your own middleware. Django ships with some built-in middleware
15- you can use right out of the box; they 're documented in the :doc:`built-in
16+ you can use right out of the box. They 're documented in the :doc:`built-in
1617middleware reference </ref/middleware>`.
1718
1819Activating middleware
1920=====================
2021
21- To activate a middleware component, add it to the :setting:`MIDDLEWARE_CLASSES`
22- list in your Django settings. In :setting:`MIDDLEWARE_CLASSES`, each middleware
23- component is represented by a string: the full Python path to the middleware's
24- class name. For example, here's the default :setting:`MIDDLEWARE_CLASSES`
25- created by :djadmin:`django-admin.py startproject <startproject>`::
22+ To activate a middleware component, add it to the
23+ :setting:`MIDDLEWARE_CLASSES` tuple in your Django settings.
24+
25+ In :setting:`MIDDLEWARE_CLASSES`, each middleware component is represented by
26+ a string: the full Python path to the middleware's class name. For example,
27+ here's the default value created by :djadmin:`django-admin.py startproject
28+ <startproject>`::
2629
2730 MIDDLEWARE_CLASSES = (
2831 'django.middleware.common.CommonMiddleware',
@@ -32,12 +35,33 @@ created by :djadmin:`django-admin.py startproject <startproject>`::
3235 'django.contrib.messages.middleware.MessageMiddleware',
3336 )
3437
35- During the request phases (:meth:`process_request` and :meth:`process_view`),
36- Django applies middleware in the order it's defined in
37- :setting:`MIDDLEWARE_CLASSES`, top-down. During the response phases
38- (:meth:`process_template_response`, :meth:`process_response`, and
39- :meth:`process_exception`), the classes are applied in reverse order, from the
40- bottom up.
38+ A Django installation doesn't require any middleware —
39+ :setting:`MIDDLEWARE_CLASSES` can be empty, if you'd like — but it's strongly
40+ suggested that you at least use
41+ :class:`~django.middleware.common.CommonMiddleware`.
42+
43+ The order in :setting:`MIDDLEWARE_CLASSES` matters because a middleware can
44+ depend on other middleware. For instance,
45+ :class:`~django.contrib.auth.middleware.AuthenticationMiddleware` stores the
46+ authenticated user in the session; therefore, it must run after
47+ :class:`~django.contrib.sessions.middleware.SessionMiddleware`.
48+
49+ Hooks and application order
50+ ===========================
51+
52+ During the request phase, before calling the view, Django applies middleware
53+ in the order it's defined in :setting:`MIDDLEWARE_CLASSES`, top-down. Two
54+ hooks are available:
55+
56+ * :meth:`process_request`
57+ * :meth:`process_view`
58+
59+ During the response phase, after calling the view, middleware are applied in
60+ reverse order, from the bottom up. Three hooks are available:
61+
62+ * :meth:`process_exception` (only if the view raised an exception)
63+ * :meth:`process_template_response` (only for template responses)
64+ * :meth:`process_response`
4165
4266.. image:: _images/middleware.svg
4367 :alt: middleware application order
@@ -47,10 +71,7 @@ bottom up.
4771If you prefer, you can also think of it like an onion: each middleware class
4872is a "layer" that wraps the view.
4973
50- A Django installation doesn't require any middleware -- e.g.,
51- :setting:`MIDDLEWARE_CLASSES` can be empty, if you'd like -- but it's strongly
52- suggested that you at least use
53- :class:`~django.middleware.common.CommonMiddleware`.
74+ The behavior of each hook is described below.
5475
5576Writing your own middleware
5677===========================
@@ -65,16 +86,19 @@ Python class that defines one or more of the following methods:
6586
6687.. method:: process_request(self, request)
6788
68- ``request`` is an :class:`~django.http.HttpRequest` object. This method is
69- called on each request, before Django decides which view to execute.
89+ ``request`` is an :class:`~django.http.HttpRequest` object.
90+
91+ ``process_request()`` is called on each request, before Django decides which
92+ view to execute.
7093
71- ``process_request()`` should return either ``None`` or an
72- :class:`~django.http.HttpResponse` object. If it returns ``None``, Django will
73- continue processing this request, executing any other middleware and, then, the
74- appropriate view. If it returns an :class:`~django.http.HttpResponse` object,
75- Django won't bother calling ANY other request, view or exception middleware, or
76- the appropriate view; it'll return that :class:`~django.http.HttpResponse`.
77- Response middleware is always called on every response.
94+ It should return either ``None`` or an :class:`~django.http.HttpResponse`
95+ object. If it returns ``None``, Django will continue processing this request,
96+ executing any other ``process_request()`` middleware, then, ``process_view()``
97+ middleware, and finally, the appropriate view. If it returns an
98+ :class:`~django.http.HttpResponse` object, Django won't bother calling any
99+ other request, view or exception middleware, or the appropriate view; it'll
100+ apply response middleware to that :class:`~django.http.HttpResponse`, and
101+ return the result.
78102
79103.. _view-middleware:
80104
@@ -91,14 +115,15 @@ dictionary of keyword arguments that will be passed to the view. Neither
91115``view_args`` nor ``view_kwargs`` include the first view argument
92116(``request``).
93117
94- ``process_view()`` is called just before Django calls the view. It should
95- return either ``None`` or an :class:`~django.http.HttpResponse` object. If it
96- returns ``None``, Django will continue processing this request, executing any
97- other ``process_view()`` middleware and, then, the appropriate view. If it
98- returns an :class:`~django.http.HttpResponse` object, Django won't bother
99- calling ANY other request, view or exception middleware, or the appropriate
100- view; it'll return that :class:`~django.http.HttpResponse`. Response
101- middleware is always called on every response.
118+ ``process_view()`` is called just before Django calls the view.
119+
120+ It should return either ``None`` or an :class:`~django.http.HttpResponse`
121+ object. If it returns ``None``, Django will continue processing this request,
122+ executing any other ``process_view()`` middleware and, then, the appropriate
123+ view. If it returns an :class:`~django.http.HttpResponse` object, Django won't
124+ bother calling any other view or exception middleware, or the appropriate
125+ view; it'll apply response middleware to that
126+ :class:`~django.http.HttpResponse`, and return the result.
102127
103128.. note::
104129
@@ -122,27 +147,25 @@ middleware is always called on every response.
122147
123148.. method:: process_template_response(self, request, response)
124149
125- ``request`` is an :class:`~django.http.HttpRequest` object. ``response`` is a
126- subclass of :class:`~django.template.response.SimpleTemplateResponse` (e.g.
127- :class:`~django.template.response.TemplateResponse`) or any response object
128- that implements a ``render`` method.
150+ ``request`` is an :class:`~django.http.HttpRequest` object. ``response`` is
151+ the :class:`~django.template.response.TemplateResponse` object (or equivalent)
152+ returned by a Django view or by a middleware.
129153
130- ``process_template_response()`` must return a response object that implements a
131- ``render`` method. It could alter the given ``response`` by changing
132- ``response.template_name`` and ``response.context_data``, or it could create
133- and return a brand-new
134- :class:`~django.template.response.SimpleTemplateResponse` or equivalent.
154+ ``process_template_response()`` is called just after the view has finished
155+ executing, if the response instance has a ``render()`` method, indicating that
156+ it is a :class:`~django.template.response.TemplateResponse` or equivalent.
135157
136- ``process_template_response()`` will only be called if the response
137- instance has a ``render()`` method, indicating that it is a
158+ It must return a response object that implements a ``render`` method. It could
159+ alter the given ``response`` by changing ``response.template_name`` and
160+ ``response.context_data``, or it could create and return a brand-new
138161:class:`~django.template.response.TemplateResponse` or equivalent.
139162
140163You don't need to explicitly render responses -- responses will be
141164automatically rendered once all template response middleware has been
142165called.
143166
144167Middleware are run in reverse order during the response phase, which
145- includes process_template_response.
168+ includes `` process_template_response()`` .
146169
147170.. _response-middleware:
148171
@@ -151,21 +174,34 @@ includes process_template_response.
151174
152175.. method:: process_response(self, request, response)
153176
154- ``request`` is an :class:`~django.http.HttpRequest` object. ``response`` is the
155- :class:`~django.http.HttpResponse` object returned by a Django view.
177+ ``request`` is an :class:`~django.http.HttpRequest` object. ``response`` is
178+ the :class:`~django.http.HttpResponse` or
179+ :class:`~django.http.StreamingHttpResponse` object returned by a Django view
180+ or by a middleware.
181+
182+ ``process_response()`` is called on all responses before they're returned to
183+ the browser.
156184
157- ``process_response()`` must return an :class:`~django.http.HttpResponse`
158- object. It could alter the given ``response``, or it could create and return a
159- brand-new :class:`~django.http.HttpResponse`.
185+ It must return an :class:`~django.http.HttpResponse` or
186+ :class:`~django.http.StreamingHttpResponse` object. It could alter the given
187+ ``response``, or it could create and return a brand-new
188+ :class:`~django.http.HttpResponse` or
189+ :class:`~django.http.StreamingHttpResponse`.
160190
161191Unlike the ``process_request()`` and ``process_view()`` methods, the
162- ``process_response()`` method is always called, even if the ``process_request()``
163- and ``process_view()`` methods of the same middleware class were skipped because
164- an earlier middleware method returned an :class:`~django.http.HttpResponse`
165- (this means that your ``process_response()`` method cannot rely on setup done in
166- ``process_request()``, for example). In addition, during the response phase the
167- classes are applied in reverse order, from the bottom up. This means classes
168- defined at the end of :setting:`MIDDLEWARE_CLASSES` will be run first.
192+ ``process_response()`` method is always called, even if the
193+ ``process_request()`` and ``process_view()`` methods of the same middleware
194+ class were skipped (because an earlier middleware method returned an
195+ :class:`~django.http.HttpResponse`). In particular, this means that your
196+ ``process_response()`` method cannot rely on setup done in
197+ ``process_request()``.
198+
199+ Finally, remember that during the response phase, middleware are applied in
200+ reverse order, from the bottom up. This means classes defined at the end of
201+ :setting:`MIDDLEWARE_CLASSES` will be run first.
202+
203+ Dealing with streaming responses
204+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
169205
170206.. versionchanged:: 1.5
171207 ``response`` may also be an :class:`~django.http.StreamingHttpResponse`
@@ -180,10 +216,17 @@ must test for streaming responses and adjust their behavior accordingly::
180216 if response.streaming:
181217 response.streaming_content = wrap_streaming_content(response.streaming_content)
182218 else:
183- response.content = wrap_content(response.content)
219+ response.content = alter_content(response.content)
220+
221+ .. note::
222+
223+ ``streaming_content`` should be assumed to be too large to hold in memory.
224+ Response middleware may wrap it in a new generator, but must not consume
225+ it. Wrapping is typically implemented as follows::
184226
185- ``streaming_content`` should be assumed to be too large to hold in memory.
186- Middleware may wrap it in a new generator, but must not consume it.
227+ def wrap_streaming_content(content)
228+ for chunk in content:
229+ yield alter_content(chunk)
187230
188231.. _exception-middleware:
189232
@@ -198,8 +241,9 @@ Middleware may wrap it in a new generator, but must not consume it.
198241Django calls ``process_exception()`` when a view raises an exception.
199242``process_exception()`` should return either ``None`` or an
200243:class:`~django.http.HttpResponse` object. If it returns an
201- :class:`~django.http.HttpResponse` object, the response will be returned to
202- the browser. Otherwise, default exception handling kicks in.
244+ :class:`~django.http.HttpResponse` object, the template response and response
245+ middleware will be applied, and the resulting response returned to the
246+ browser. Otherwise, default exception handling kicks in.
203247
204248Again, middleware are run in reverse order during the response phase, which
205249includes ``process_exception``. If an exception middleware returns a response,
@@ -224,9 +268,9 @@ Marking middleware as unused
224268~~~~~~~~~~~~~~~~~~~~~~~~~~~~
225269
226270It's sometimes useful to determine at run-time whether a piece of middleware
227- should be used. In these cases, your middleware's ``__init__`` method may raise
228- `` django.core.exceptions.MiddlewareNotUsed`` . Django will then remove that
229- piece of middleware from the middleware process.
271+ should be used. In these cases, your middleware's ``__init__`` method may
272+ raise :exc:` django.core.exceptions.MiddlewareNotUsed`. Django will then remove
273+ that piece of middleware from the middleware process.
230274
231275Guidelines
232276----------
0 commit comments