Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 393 lines (288 sloc) 17.213 kb
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
1 ======================
2 Chapter 17: Middleware
3 ======================
4
5 On occasion, you'll need to run a piece of code on each and every request that
6 Django handles. This code might need to modify the request before the view
7 handles it, it might need to log information about the request for debugging
8 purposes, and so forth.
9
10 You can do this with Django's *middleware* framework, which is a set of hooks
11 into Django's request/response processing. It's a light, low-level "plug-in"
12 system capable of globally altering both Django's input and output.
13
14 Each middleware component is responsible for doing some specific function. If
15 you're reading this book straight through, you've seen middleware a number of
16 times already:
17
18 * All of the session and user tools that we looked at in Chapter 14
19 are made possible by a few small pieces of middleware (more
20 specifically, the middleware makes ``request.session`` and
21 ``request.user`` available to you in views).
22
23 * The sitewide cache discussed in Chapter 15 is actually just a piece
24 of middleware that bypasses the call to your view function if the
25 response for that view has already been cached.
26
27 * The ``flatpages``, ``redirects``, and ``csrf`` applications from
28 Chapter 16 all do their magic through middleware components.
29
30 This chapter dives deeper into exactly what middleware is and how it works,
31 and explains how you can write your own middleware.
32
33 What's Middleware?
34 ==================
35
36 Let's start with a very simple example.
37
38 High-traffic sites often need to deploy Django behind a load-balancing proxy
39 (see Chapter 12). This can cause a few small complications, one of which is
40 that every request's remote IP (``request.META["REMOTE_IP"]``) will be that of
41 the load balancer, not the actual IP making the request. Load balancers deal
42 with this by setting a special header, ``X-Forwarded-For``, to the actual
43 requesting IP address.
44
45 So here's a small bit of middleware that lets sites running behind a proxy
46 still see the correct IP address in ``request.META["REMOTE_ADDR"]``::
47
48 class SetRemoteAddrFromForwardedFor(object):
49 def process_request(self, request):
50 try:
51 real_ip = request.META['HTTP_X_FORWARDED_FOR']
52 except KeyError:
53 pass
54 else:
55 # HTTP_X_FORWARDED_FOR can be a comma-separated list of IPs.
56 # Take just the first one.
57 real_ip = real_ip.split(",")[0]
58 request.META['REMOTE_ADDR'] = real_ip
59
60 (Note: Although the HTTP header is called ``X-Forwarded-For``, Django makes
61 it available as ``request.META['HTTP_X_FORWARDED_FOR']``. With the exception
62 of ``content-length`` and ``content-type``, any HTTP headers in the request are
63 converted to ``request.META`` keys by converting all characters to uppercase,
64 replacing any hyphens with underscores and adding an ``HTTP_`` prefix to the
65 name.)
66
67 If this middleware is installed (see the next section), every request's
68 ``X-Forwarded-For`` value will be automatically inserted into
69 ``request.META['REMOTE_ADDR']``. This means your Django applications don't need
70 to be concerned with whether they're behind a load-balancing proxy or not; they
71 can simply access ``request.META['REMOTE_ADDR']``, and that will work whether
72 or not a proxy is being used.
73
74 In fact, this is a common enough need that this piece of middleware is a
75 built-in part of Django. It lives in ``django.middleware.http``, and you can
76 read a bit more about it later in this chapter.
77
78 Middleware Installation
79 =======================
80
81 If you've read this book straight through, you've already seen a number of
82 examples of middleware installation; many of the examples in previous chapters
83 have required certain middleware. For completeness, here's how to install
84 middleware.
85
86 To activate a middleware component, add it to the ``MIDDLEWARE_CLASSES`` tuple
87 in your settings module. In ``MIDDLEWARE_CLASSES``, each middleware component
88 is represented by a string: the full Python path to the middleware's class
89 name. For example, here's the default ``MIDDLEWARE_CLASSES`` created by
90 ``django-admin.py startproject``::
91
92 MIDDLEWARE_CLASSES = (
93 'django.middleware.common.CommonMiddleware',
94 'django.contrib.sessions.middleware.SessionMiddleware',
95 'django.contrib.auth.middleware.AuthenticationMiddleware',
96 )
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
97
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
98 A Django installation doesn't require any middleware -- ``MIDDLEWARE_CLASSES``
99 can be empty, if you'd like -- but we recommend that you activate
100 ``CommonMiddleware``, which we explain shortly.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
101
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
102 The order is significant. On the request and view phases, Django applies
103 middleware in the order given in ``MIDDLEWARE_CLASSES``, and on the response
104 and exception phases, Django applies middleware in reverse order. That is,
105 Django treats ``MIDDLEWARE_CLASSES`` as a sort of "wrapper" around the view
106 function: on the request it walks down the list to the view, and on the
107 response it walks back up.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
108
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
109 Middleware Methods
110 ==================
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
111
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
112 Now that you know what middleware is and how to install it, let's take a look at
113 all the available methods that middleware classes can define.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
114
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
115 Initializer: __init__(self)
116 ---------------------------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
117
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
118 Use ``__init__()`` to perform systemwide setup for a given middleware class.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
119
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
120 For performance reasons, each activated middleware class is instantiated only
121 *once* per server process. This means that ``__init__()`` is called only once
122 -- at server startup -- not for individual requests.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
123
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
124 A common reason to implement an ``__init__()`` method is to check whether the
125 middleware is indeed needed. If ``__init__()`` raises
126 ``django.core.exceptions.MiddlewareNotUsed``, then Django will remove the
127 middleware from the middleware stack. You might use this feature to check for
128 some piece of software that the middleware class requires, or check whether
129 the server is running debug mode, or any other such environment situation.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
130
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
131 If a middleware class defines an ``__init__()`` method, the method should take no
132 arguments beyond the standard ``self``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
133
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
134 Request Preprocessor: process_request(self, request)
135 ----------------------------------------------------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
136
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
137 This method gets called as soon as the request has been received -- before
138 Django has parsed the URL to determine which view to execute. It gets passed
139 the ``HttpRequest`` object, which you may modify at will.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
140
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
141 ``process_request()`` should return either ``None`` or an ``HttpResponse``
142 object.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
143
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
144 * If it returns ``None``, Django will continue processing this request,
145 executing any other middleware and then the appropriate view.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
146
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
147 * If it returns an ``HttpResponse`` object, Django won't bother calling
148 *any* other middleware (of any type) or the appropriate view. Django
149 will immediately return that ``HttpResponse``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
150
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
151 View Preprocessor: process_view(self, request, view, args, kwargs)
152 ------------------------------------------------------------------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
153
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
154 This method gets called after the request preprocessor is called and Django
155 has determined which view to execute, but before that view has actually been
156 executed.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
157
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
158 The arguments passed to this view are shown in Table 17-1.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
159
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
160 .. table:: Table 17-1. Arguments Passed to process_view()
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
161
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
162 ============== ==========================================================
163 Argument Explanation
164 ============== ==========================================================
165 ``request`` The ``HttpRequest`` object.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
166
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
167 ``view`` The Python function that Django will call to handle this
168 request. This is the actual function object itself,
169 not the name of the function as a string.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
170
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
171 ``args`` The list of positional arguments that will be passed to
172 the view, not including the ``request`` argument (which
173 is always the first argument to a view).
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
174
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
175 ``kwargs`` The dictionary of keyword arguments that will be passed
176 to the view.
177 ============== ==========================================================
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
178
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
179 Just like ``process_request()``, ``process_view()`` should return either
180 ``None`` or an ``HttpResponse`` object.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
181
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
182 * If it returns ``None``, Django will continue processing this request,
183 executing any other middleware and then the appropriate view.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
184
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
185 * If it returns an ``HttpResponse`` object, Django won't bother calling
186 *any* other middleware (of any type) or the appropriate view. Django
187 will immediately return that ``HttpResponse``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
188
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
189 Response Postprocessor: process_response(self, request, response)
190 -----------------------------------------------------------------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
191
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
192 This method gets called after the view function is called and the response is
193 generated. Here, the processor can modify the content of a response. One
194 obvious use case is content compression, such as gzipping of the request's
195 HTML.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
196
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
197 The parameters should be pretty self-explanatory: ``request`` is the request
198 object, and ``response`` is the response object returned from the view.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
199
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
200 Unlike the request and view preprocessors, which may return ``None``,
201 ``process_response()`` *must* return an ``HttpResponse`` object. That response
202 could be the original one passed into the function (possibly modified) or a
203 brand-new one.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
204
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
205 Exception Postprocessor: process_exception(self, request, exception)
206 --------------------------------------------------------------------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
207
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
208 This method gets called only if something goes wrong and a view raises an
209 uncaught exception. You can use this hook to send error notifications, dump
210 postmortem information to a log, or even try to recover from the error
211 automatically.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
212
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
213 The parameters to this function are the same ``request`` object we've been
214 dealing with all along, and ``exception``, which is the actual ``Exception``
215 object raised by the view function.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
216
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
217 ``process_exception()`` should return a either ``None`` or an ``HttpResponse``
218 object.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
219
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
220 * If it returns ``None``, Django will continue processing this request
221 with the framework's built-in exception handling.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
222
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
223 * If it returns an ``HttpResponse`` object, Django will use that response
224 instead of the framework's built-in exception handling.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
225
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
226 .. note::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
227
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
228 Django ships with a number of middleware classes (discussed in the following
229 section) that make good examples. Reading the code for them should give you
230 a good feel for the power of middleware.
231
232 You can also find a number of community-contributed examples on Django's
233 wiki: http://code.djangoproject.com/wiki/ContributedMiddleware
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
234
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
235 Built-in Middleware
236 ===================
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
237
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
238 Django comes with some built-in middleware to deal with common problems, which we discuss
239 in the sections that follow.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
240
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
241 Authentication Support Middleware
242 ---------------------------------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
243
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
244 Middleware class: ``django.contrib.auth.middleware.AuthenticationMiddleware``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
245
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
246 This middleware enables authentication support. It adds the ``request.user``
247 attribute, representing the currently logged-in user, to every incoming
248 ``HttpRequest`` object.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
249
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
250 See Chapter 14 for complete details.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
251
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
252 "Common" Middleware
253 -------------------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
254
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
255 Middleware class: ``django.middleware.common.CommonMiddleware``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
256
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
257 This middleware adds a few conveniences for perfectionists:
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
258
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
259 * *Forbids access to user agents in the ``DISALLOWED_USER_AGENTS`` setting*:
260 If provided, this setting should be a list of compiled regular expression
261 objects that are matched against the user-agent header for each incoming
262 request. Here's an example snippet from a settings file::
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
263
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
264 import re
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
265
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
266 DISALLOWED_USER_AGENTS = (
267 re.compile(r'^OmniExplorer_Bot'),
268 re.compile(r'^Googlebot')
269 )
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
270
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
271 Note the ``import re``, because ``DISALLOWED_USER_AGENTS`` requires its
272 values to be compiled regexes (i.e., the output of ``re.compile()``).
273 The settings file is regular Python, so it's perfectly OK to include
274 Python ``import`` statements in it.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
275
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
276 * *Performs URL rewriting based on the ``APPEND_SLASH`` and ``PREPEND_WWW``
277 settings*: If ``APPEND_SLASH`` is ``True``, URLs that lack a trailing
278 slash will be redirected to the same URL with a trailing slash, unless
279 the last component in the path contains a period. So ``foo.com/bar`` is
280 redirected to ``foo.com/bar/``, but ``foo.com/bar/file.txt`` is passed
281 through unchanged.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
282
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
283 If ``PREPEND_WWW`` is ``True``, URLs that lack a leading "www." will be
284 redirected to the same URL with a leading "www.".
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
285
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
286 Both of these options are meant to normalize URLs. The philosophy is
287 that each URL should exist in one -- and only one -- place. Technically the
288 URL ``example.com/bar`` is distinct from ``example.com/bar/``, which in
289 turn is distinct from ``www.example.com/bar/``. A search-engine indexer
290 would treat these as separate URLs, which is detrimental to your site's
291 search-engine rankings, so it's a best practice to normalize URLs.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
292
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
293 * *Handles ETags based on the ``USE_ETAGS`` setting*: *ETags* are an HTTP-level
294 optimization for caching pages conditionally. If ``USE_ETAGS`` is
295 set to ``True``, Django will calculate an ETag for each request by
296 MD5-hashing the page content, and it will take care of sending ``Not
297 Modified`` responses, if appropriate.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
298
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
299 Note there is also a conditional ``GET`` middleware, covered shortly, which
300 handles ETags and does a bit more.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
301
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
302 Compression Middleware
303 ----------------------
304
305 Middleware class: ``django.middleware.gzip.GZipMiddleware``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
306
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
307 This middleware automatically compresses content for browsers that understand gzip
308 compression (all modern browsers). This can greatly reduce the amount of bandwidth
309 a Web server consumes. The tradeoff is that it takes a bit of processing time to
310 compress pages.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
311
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
312 We usually prefer speed over bandwidth, but if you prefer the reverse, just
313 enable this middleware.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
314
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
315 Conditional GET Middleware
316 --------------------------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
317
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
318 Middleware class: ``django.middleware.http.ConditionalGetMiddleware``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
319
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
320 This middleware provides support for conditional ``GET`` operations. If the response
321 has an ``Last-Modified`` or ``ETag`` or header, and the request has ``If-None-Match``
322 or ``If-Modified-Since``, the response is replaced by an 304 ("Not modified")
323 response. ``ETag`` support depends on on the ``USE_ETAGS`` setting and expects
324 the ``ETag`` response header to already be set. As discussed above, the ``ETag``
325 header is set by the Common middleware.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
326
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
327 It also removes the content from any response to a ``HEAD`` request and sets the
328 ``Date`` and ``Content-Length`` response headers for all requests.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
329
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
330 Reverse Proxy Support (X-Forwarded-For Middleware)
331 --------------------------------------------------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
332
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
333 Middleware class: ``django.middleware.http.SetRemoteAddrFromForwardedFor``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
334
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
335 This is the example we examined in the "What's Middleware?" section earlier. It
336 sets ``request.META['REMOTE_ADDR']`` based on
337 ``request.META['HTTP_X_FORWARDED_FOR']``, if the latter is set. This is useful
338 if you're sitting behind a reverse proxy that causes each request's
339 ``REMOTE_ADDR`` to be set to ``127.0.0.1``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
340
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
341 .. admonition:: Danger!
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
342
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
343 This middleware does *not* validate ``HTTP_X_FORWARDED_FOR``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
344
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
345 If you're not behind a reverse proxy that sets ``HTTP_X_FORWARDED_FOR``
346 automatically, do not use this middleware. Anybody can spoof the value of
347 ``HTTP_X_FORWARDED_FOR``, and because this sets ``REMOTE_ADDR`` based on
348 ``HTTP_X_FORWARDED_FOR``, that means anybody can fake his IP address.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
349
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
350 Only use this middleware when you can absolutely trust the value of
351 ``HTTP_X_FORWARDED_FOR``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
352
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
353 Session Support Middleware
354 --------------------------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
355
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
356 Middleware class: ``django.contrib.sessions.middleware.SessionMiddleware``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
357
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
358 This middleware enables session support. See Chapter 14 for details.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
359
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
360 Sitewide Cache Middleware
361 -------------------------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
362
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
363 Middleware classes: ``django.middleware.cache.UpdateCacheMiddleware`` and
364 ``django.middleware.cache.FetchFromCacheMiddleware``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
365
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
366 These middlewares work together to cache each Django-powered page. This was
367 discussed in detail in Chapter 15.
368
369 Transaction Middleware
370 ----------------------
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
371
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
372 Middleware class: ``django.middleware.transaction.TransactionMiddleware``.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
373
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
374 This middleware binds a database ``COMMIT`` or ``ROLLBACK`` to the request/response
375 phase. If a view function runs successfully, a ``COMMIT`` is issued. If the view
376 raises an exception, a ``ROLLBACK`` is issued.
377
378 The order of this middleware in the stack is important. Middleware modules
379 running outside of it run with commit-on-save -- the default Django behavior.
380 Middleware modules running inside it (coming later in the stack) will be under
381 the same transaction control as the view functions.
382
383 See Appendix B for more about information about database transactions.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
384
385 What's Next?
386 ============
387
d40cfe7 @jacobian Restored *2.0* version of the book, not 1.0!
jacobian authored
388 Web developers and database-schema designers don't always have the luxury of
389 starting from scratch. In the `next chapter`_, we'll cover how to integrate with
390 legacy systems, such as database schemas you've inherited from the 1980s.
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
391
392 .. _next chapter: ../chapter18/
Something went wrong with that request. Please try again.