Skip to content
100644 682 lines (501 sloc) 28.1 KB
acc918f @jacobian Initial import of djangobook from private SVN repo.
jacobian authored
1 ===================
2 Chapter 13: Caching
3 ===================
5 Static Web sites, in which simple files are served directly to the Web, scale
6 like crazy. But a fundamental tradeoff in dynamic Web sites is, well, they're
7 dynamic. Each time a user requests a page, the Web server makes all sorts of
8 calculations--from database queries, to template rendering, to business logic--
9 to create the page that your site's visitor sees. From a processing-overhead
10 perspective, this is quite expensive.
12 For most Web applications, this overhead isn't a big deal. Most Web applications
13 aren't or Slashdot; they're simply small- to medium-sized
14 sites with so-so traffic. But for medium- to high-traffic sites, it's essential
15 to cut as much overhead as possible. That's where caching comes in.
17 To *cache* something is to save the result of an expensive calculation so that
18 you don't have to perform the calculation next time. Here's some pseudocode
19 explaining how this would work for a dynamically generated Web page::
21 given a URL, try finding that page in the cache
22 if the page is in the cache:
23 return the cached page
24 else:
25 generate the page
26 save the generated page in the cache (for next time)
27 return the generated page
29 Django comes with a robust cache system that lets you save dynamic pages so
30 they don't have to be calculated for each request. For convenience, Django
31 offers different levels of cache granularity. You can cache the response of
32 specific views, you can cache only the pieces that are difficult to produce, or
33 you can cache your entire site.
35 Django also works well with "upstream" caches, such as Squid
36 ( and browser-based caches. These are the types of
37 caches that you don't directly control but to which you can provide hints (via
38 HTTP headers) about which parts of your site should be cached, and how.
40 Read on to discover how to use Django's caching system. When your site gets
41 Slashdotted you'll be happy you understand this material.
43 Setting Up the Cache
44 ====================
46 The cache system requires a small amount of setup. Namely, you have to tell it
47 where your cached data should live, whether in a database, on the filesystem,
48 or directly in memory. This is an important decision that affects your cache's
49 performance (yes, some cache types are faster than others). In-memory caching
50 will generally be much faster than filesystem or database caching, because it
51 lacks the overhead of hitting the filesystem or database.
53 Your cache preference goes in the ``CACHE_BACKEND`` setting in your settings
54 file. If you use caching and do not specify ``CACHE_BACKEND``, Django will use
55 ``simple:///`` by default. The following sections explain all available values
56 for ``CACHE_BACKEND``.
58 Memcached
59 ---------
61 By far the fastest, most efficient type of cache available to Django, Memcached
62 is an entirely memory-based cache framework originally developed to handle high
63 loads at LiveJournal ( and subsequently open-sourced
64 by Danga Interactive ( It's used by sites such as Slashdot
65 and Wikipedia to reduce database access and dramatically increase site
66 performance.
68 Memcached is available for free at It runs as a
69 daemon and is allotted a specified amount of RAM. Its primary feature is to
70 provide an interface--a *super-lightning-fast* interface--for adding,
71 retrieving, and deleting arbitrary data in the cache. All data is stored
72 directly in memory, so there's no overhead of database or filesystem usage.
74 After installing Memcached itself, you'll need to install the Memcached Python
75 bindings, which are not bundled with Django directly. These bindings are in a
76 single Python module, ````, which is available at
79 To use Memcached with Django, set ``CACHE_BACKEND`` to
80 ``memcached://ip:port/``, where ``ip`` is the IP address of the Memcached
81 daemon and ``port`` is the port on which Memcached is running.
83 In this example, Memcached is running on localhost ( port 11211::
85 CACHE_BACKEND = 'memcached://'
87 One excellent feature of Memcached is its ability to share cache over multiple
88 servers. This means you can run Memcached daemons on multiple machines, and the
89 program will treat the group of machines as a *single* cache, without the need
90 to duplicate cache values on each machine. To take advantage of this feature
91 with Django, include all server addresses in ``CACHE_BACKEND``, separated by
92 semicolons.
94 In this example, the cache is shared over Memcached instances running on the IP
95 addresses and, both of which are on port 11211::
97 CACHE_BACKEND = 'memcached://;'
99 In the following example, the cache is shared over Memcached instances running
100 on the IP addresses (port 11211), (port 11212), and
101 (port 11213)::
103 CACHE_BACKEND = 'memcached://;;'
105 A final point about Memcached is that memory-based caching has one important
106 disadvantage. Because the cached data is stored only in memory, the data will
107 be lost if your server crashes. Clearly, memory isn't intended for permanent
108 data storage, so don't rely on memory-based caching as your only data storage.
109 Without a doubt, *none* of the Django caching back-ends should be used for
110 permanent storage--they're all intended to be solutions for caching, not
111 storage--but we point this out here because memory-based caching is
112 particularly temporary.
114 Database Caching
115 ----------------
117 To use a database table as your cache back-end, create a cache table in your
118 database and point Django's cache system at that table.
120 First, create a cache table by running this command::
122 python createcachetable [cache_table_name]
124 where ``[cache_table_name]`` is the name of the database table to create.
125 This name can be whatever you want, as long as it's a valid table name that's
126 not already being used in your database. This command creates a single table
127 in your database that is in the proper format Django's database-cache system
128 expects.
130 Once you've created that database table, set your ``CACHE_BACKEND`` setting to
131 ``"db://tablename"``, where ``tablename`` is the name of the database table.
132 In this example, the cache table's name is ``my_cache_table``::
134 CACHE_BACKEND = 'db://my_cache_table'
136 The database caching back-end uses the same database as specified in your
137 settings file. You can't use a different database back-end for your cache table.
139 Filesystem Caching
140 ------------------
142 To store cached items on a filesystem, use the ``"file://"`` cache type for
143 ``CACHE_BACKEND``, specifying the directory on your filesystem that should
144 store the cached data.
146 For example, to store cached data in ``/var/tmp/django_cache``, use this setting::
148 CACHE_BACKEND = 'file:///var/tmp/django_cache'
150 Note that there are three forward slashes toward the beginning of the preceding
151 example. The first two are for ``file://``, and the third is the first character
152 of the directory path, ``/var/tmp/django_cache``. If you're on Windows, put the
153 drive letter after the ``file://``, like so:: ``file://c:/foo/bar``.
155 The directory path should be *absolute*--that is, it should start at the root
156 of your filesystem. It doesn't matter whether you put a slash at the end of the
157 setting.
159 Make sure the directory pointed to by this setting exists and is readable and
160 writable by the system user under which your Web server runs. Continuing the
161 preceding example, if your server runs as the user ``apache``, make sure the
162 directory ``/var/tmp/django_cache`` exists and is readable and writable by the
163 user ``apache``.
165 Each cache value will be stored as a separate file whose contents are the
166 cache data saved in a serialized ("pickled") format, using Python's ``pickle``
167 module. Each file's name is the cache key, escaped for safe filesystem use.
169 Local-Memory Caching
170 --------------------
172 If you want the speed advantages of in-memory caching but don't have the
173 capability of running Memcached, consider the local-memory cache back-end. This
174 cache is per-process and thread-safe, but it isn't as efficient as Memcached
175 due to its simplistic locking and memory allocation strategies.
177 To use it, set ``CACHE_BACKEND`` to ``'locmem:///'``, for example::
179 CACHE_BACKEND = 'locmem:///'
181 Simple Caching (for Development)
182 --------------------------------
184 A simple, single-process memory cache is available as ``'simple:///'``, for example::
186 CACHE_BACKEND = 'simple:///'
188 This cache merely saves cached data in process, which means it should be used only in
189 development or testing environments.
191 Dummy Caching (for Development)
192 -------------------------------
194 Finally, Django comes with a "dummy" cache that doesn't actually cache; it
195 just implements the cache interface without doing anything.
197 This is useful if you have a production site that uses heavy-duty caching in
198 various places and a development/test environment on which you don't want to
199 cache. In that case, set ``CACHE_BACKEND`` to ``'dummy:///'`` in the settings
200 file for your development environment, for example::
202 CACHE_BACKEND = 'dummy:///'
204 As a result, your development environment won't use caching, but your
205 production environment still will.
207 CACHE_BACKEND Arguments
208 -----------------------
210 Each cache back-end may take arguments. They're given in query-string style on
211 the ``CACHE_BACKEND`` setting. Valid arguments are as follows:
213 * ``timeout``: The default timeout, in seconds, to use for the cache.
214 This argument defaults to 300 seconds (5 minutes).
216 * ``max_entries``: For the simple, local-memory, and database back-ends,
217 the maximum number of entries allowed in the cache before old values are
218 deleted. This argument defaults to 300.
220 * ``cull_frequency``: The ratio of entries that are culled when
221 ``max_entries`` is reached. The actual ratio is ``1/cull_frequency``, so
222 set ``cull_frequency=2`` to cull half of the entries when ``max_entries``
223 is reached.
225 A value of ``0`` for ``cull_frequency`` means that the entire cache will
226 be dumped when ``max_entries`` is reached. This makes culling *much*
227 faster at the expense of more cache misses. This argument defaults to 3.
229 In this example, ``timeout`` is set to ``60``::
231 CACHE_BACKEND = "locmem:///?timeout=60"
233 In this example, ``timeout`` is ``30`` and ``max_entries`` is ``400``::
235 CACHE_BACKEND = "locmem:///?timeout=30&max_entries=400"
237 Invalid arguments are silently ignored, as are invalid values of known
238 arguments.
240 The Per-Site Cache
241 ==================
243 Once you've specified ``CACHE_BACKEND``, the simplest way to use caching is to
244 cache your entire site. This means each page that doesn't have GET or POST
245 parameters will be cached for a specified amount of time the first time it's
246 requested.
248 To activate the per-site cache, just add
249 ``'django.middleware.cache.CacheMiddleware'`` to your ``MIDDLEWARE_CLASSES``
250 setting, as in this example::
253 'django.middleware.cache.CacheMiddleware',
254 'django.middleware.common.CommonMiddleware',
255 )
257 .. note::
259 The order of ``MIDDLEWARE_CLASSES`` matters. See the section "Order of
260 MIDDLEWARE_CLASSES" later in this chapter.
262 Then, add the following required settings to your Django settings file:
264 * ``CACHE_MIDDLEWARE_SECONDS``: The number of seconds each page should be
265 cached.
267 * ``CACHE_MIDDLEWARE_KEY_PREFIX``: If the cache is shared across multiple
268 sites using the same Django installation, set this to the name of the
269 site, or some other string that is unique to this Django instance, to
270 prevent key collisions. Use an empty string if you don't care.
272 The cache middleware caches every page that doesn't have GET or POST
273 parameters. That is, if a user requests a page and passes GET parameters in a
274 query string, or passes POST parameters, the middleware will *not* attempt to
275 retrieve a cached version of the page. If you intend to use the per-site cache,
276 keep this in mind as you design your application; don't use URLs with query
277 strings, for example, unless it is acceptable for your application not to cache
278 those pages.
280 The cache middleware supports another setting,
281 ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY``. If you've defined this setting, and it's
282 set to ``True``, then the cache middleware will only cache anonymous requests
283 (i.e., those requests made by a non-logged-in user). This is a simple and
284 effective way of disabling caching for any user-specific pages, such as Django's
285 admin interface. Note that if you use ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY``, you
286 should make sure you've activated ``AuthenticationMiddleware`` and that
287 ``AuthenticationMiddleware`` appears before ``CacheMiddleware`` in your
290 Finally, note that ``CacheMiddleware`` automatically sets a few headers in each
291 ``HttpResponse``:
293 * It sets the ``Last-Modified`` header to the current date/time when a fresh
294 (uncached) version of the page is requested.
296 * It sets the ``Expires`` header to the current date/time plus the defined
299 * It sets the ``Cache-Control`` header to give a maximum age for the page,
300 again from the ``CACHE_MIDDLEWARE_SECONDS`` setting.
302 The Per-View Cache
303 ==================
305 A more granular way to use the caching framework is by caching the output of
306 individual views. This has the same effects as the per-site cache (including the
307 omission of caching on requests with GET and POST parameters). It applies to
308 whichever views you specify, rather than the whole site.
310 Do this by using a *decorator*, which is a wrapper around your view function
311 that alters its behavior to use caching. The per-view cache decorator is called
312 ``cache_page`` and is located in the ``django.views.decorators.cache`` module,
313 for example::
315 from django.views.decorators.cache import cache_page
317 def my_view(request, param):
318 # ...
319 my_view = cache_page(my_view, 60 * 15)
321 Alternatively, if you're using Python 2.4 or greater, you can use decorator
322 syntax. This example is equivalent to the preceding one::
324 from django.views.decorators.cache import cache_page
326 @cache_page(60 * 15)
327 def my_view(request, param):
328 # ...
330 ``cache_page`` takes a single argument: the cache timeout, in seconds. In the
331 preceding example, the result of the ``my_view()`` view will be cached for 15
332 minutes. (Note that we've written it as ``60 * 15`` for the purpose of
333 readability. ``60 * 15`` will be evaluated to ``900``--that is, 15 minutes
334 multiplied by 60 seconds per minute.)
336 The per-view cache, like the per-site cache, is keyed off of the URL. If
337 multiple URLs point at the same view, each URL will be cached separately.
338 Continuing the ``my_view`` example, if your URLconf looks like this::
340 urlpatterns = ('',
341 (r'^foo/(\d{1,2})/$', my_view),
342 )
344 then requests to ``/foo/1/`` and ``/foo/23/`` will be cached separately, as
345 you may expect. But once a particular URL (e.g., ``/foo/23/``) has been
346 requested, subsequent requests to that URL will use the cache.
348 Specifying Per-View Cache in the URLconf
349 ----------------------------------------
351 The examples in the previous section have hard-coded the fact that the view is
352 cached, because ``cache_page`` alters the ``my_view`` function in place. This
353 approach couples your view to the cache system, which is not ideal for several
354 reasons. For instance, you might want to reuse the view functions on another,
355 cacheless site, or you might want to distribute the views to people who might
356 want to use them without being cached. The solution to these problems is to
357 specify the per-view cache in the URLconf rather than next to the view functions
358 themselves.
360 Doing so is easy: simply wrap the view function with ``cache_page`` when you
361 refer to it in the URLconf. Here's the old URLconf from earlier::
363 urlpatterns = ('',
364 (r'^foo/(\d{1,2})/$', my_view),
365 )
367 Here's the same thing, with ``my_view`` wrapped in ``cache_page``::
369 from django.views.decorators.cache import cache_page
371 urlpatterns = ('',
372 (r'^foo/(\d{1,2})/$', cache_page(my_view, 60 * 15)),
373 )
375 If you take this approach, don't forget to import ``cache_page`` within your
376 URLconf.
378 The Low-Level Cache API
379 =======================
381 Sometimes, caching an entire rendered page doesn't gain you very much and is,
382 in fact, inconvenient overkill.
384 Perhaps, for instance, your site includes a view whose results depend on
385 several expensive queries, the results of which change at different intervals.
386 In this case, it would not be ideal to use the full-page caching that the
387 per-site or per-view cache strategies offer, because you wouldn't want to
388 cache the entire result (since some of the data changes often), but you'd still
389 want to cache the results that rarely change.
391 For cases like this, Django exposes a simple, low-level cache API, which lives
392 in the module ``django.core.cache``. You can use the low-level cache API to
393 store objects in the cache with any level of granularity you like. You can cache
394 any Python object that can be pickled safely: strings, dictionaries, lists of
395 model objects, and so forth. (Most common Python objects can be pickled; refer
396 to the Python documentation for more information about pickling.)
398 Here's how to import the API::
400 >>> from django.core.cache import cache
402 The basic interface is ``set(key, value, timeout_seconds)`` and ``get(key)``::
404 >>> cache.set('my_key', 'hello, world!', 30)
405 >>> cache.get('my_key')
406 'hello, world!'
408 The ``timeout_seconds`` argument is optional and defaults to the ``timeout``
409 argument in the ``CACHE_BACKEND`` setting explained earlier.
411 If the object doesn't exist in the cache, or the cache back-end is unreachable,
412 ``cache.get()`` returns ``None``::
414 # Wait 30 seconds for 'my_key' to expire...
416 >>> cache.get('my_key')
417 None
419 >>> cache.get('some_unset_key')
420 None
422 We advise against storing the literal value ``None`` in the cache, because you
423 won't be able to distinguish between your stored ``None`` value and a cache
424 miss signified by a return value of ``None``.
426 ``cache.get()`` can take a ``default`` argument. This specifies which value to
427 return if the object doesn't exist in the cache::
429 >>> cache.get('my_key', 'has expired')
430 'has expired'
432 To retrieve multiple cache values in a single shot, use ``cache.get_many()``.
433 If possible for the given cache back-end, ``get_many()`` will hit the cache only
434 once, as opposed to hitting it once per cache key. ``get_many()`` returns a
435 dictionary with all of the keys you asked for that exist in the cache and
436 haven't expired::
438 >>> cache.set('a', 1)
439 >>> cache.set('b', 2)
440 >>> cache.set('c', 3)
441 >>> cache.get_many(['a', 'b', 'c'])
442 {'a': 1, 'b': 2, 'c': 3}
444 If a cache key doesn't exist or is expired, it won't be included in the
445 dictionary. The following is a continuation of the example::
447 >>> cache.get_many(['a', 'b', 'c', 'd'])
448 {'a': 1, 'b': 2, 'c': 3}
450 Finally, you can delete keys explicitly with ``cache.delete()``. This is an
451 easy way of clearing the cache for a particular object::
453 >>> cache.delete('a')
455 ``cache.delete()`` has no return value, and it works the same way whether or
456 not a value with the given cache key exists.
458 Upstream Caches
459 ===============
461 So far, this chapter has focused on caching your *own* data. But another type
462 of caching is relevant to Web development, too: caching performed by *upstream*
463 caches. These are systems that cache pages for users even before the request
464 reaches your Web site.
466 Here are a few examples of upstream caches:
468 * Your ISP may cache certain pages, so if you requested a page from
469, your ISP would send you the page without having to
470 access directly. The maintainers of have no
471 knowledge of this caching; the ISP sits between and your Web
472 browser, handling all of the caching transparently.
474 * Your Django Web site may sit behind a *proxy cache*, such as Squid Web
475 Proxy Cache (, that caches pages for
476 performance. In this case, each request first would be handled by the
477 proxy, and it would be passed to your application only if needed.
479 * Your Web browser caches pages, too. If a Web page sends out the
480 appropriate headers, your browser will use the local cached copy for
481 subsequent requests to that page, without even contacting the Web page
482 again to see whether it has changed.
484 Upstream caching is a nice efficiency boost, but there's a danger to it. The
485 content of many Web pages differs based on authentication and a host of other
486 variables, and cache systems that blindly save pages based purely on URLs could
487 expose incorrect or sensitive data to subsequent visitors to those pages.
489 For example, say you operate a Web e-mail system, and the contents of the
490 "inbox" page obviously depend on which user is logged in. If an ISP blindly
491 cached your site, then the first user who logged in through that ISP would have
492 his or her user-specific inbox page cached for subsequent visitors to the site.
493 That's not cool.
495 Fortunately, HTTP provides a solution to this problem. A number of HTTP headers
496 exist to instruct upstream caches to differ their cache contents depending on
497 designated variables, and to tell caching mechanisms not to cache particular
498 pages. We'll look at some of these headers in the sections that follow.
500 Using Vary Headers
501 ------------------
503 The ``Vary`` header defines which request headers a cache
504 mechanism should take into account when building its cache key. For example, if
505 the contents of a Web page depend on a user's language preference, the page is
506 said to "vary on language."
508 By default, Django's cache system creates its cache keys using the requested
509 path (e.g., ``"/stories/2005/jun/23/bank_robbed/"``). This means every request
510 to that URL will use the same cached version, regardless of user-agent
511 differences such as cookies or language preferences. However, if this page
512 produces different content based on some difference in request headers--such
513 as a cookie, or a language, or a user-agent--you'll need to use the ``Vary``
514 header to tell caching mechanisms that the page output depends on those things.
516 To do this in Django, use the convenient ``vary_on_headers`` view decorator,
517 like so::
519 from django.views.decorators.vary import vary_on_headers
521 # Python 2.3 syntax.
522 def my_view(request):
523 # ...
524 my_view = vary_on_headers(my_view, 'User-Agent')
526 # Python 2.4+ decorator syntax.
527 @vary_on_headers('User-Agent')
528 def my_view(request):
529 # ...
531 In this case, a caching mechanism (such as Django's own cache middleware) will
532 cache a separate version of the page for each unique user-agent.
534 The advantage to using the ``vary_on_headers`` decorator rather than manually
535 setting the ``Vary`` header (using something like
536 ``response['Vary'] = 'user-agent'``) is that the decorator *adds* to the
537 ``Vary`` header (which may already exist), rather than setting it from scratch
538 and potentially overriding anything that was already in there.
540 You can pass multiple headers to ``vary_on_headers()``::
542 @vary_on_headers('User-Agent', 'Cookie')
543 def my_view(request):
544 # ...
546 This tells upstream caches to vary on *both*, which means each combination of
547 user-agent and cookie will get its own cache value. For example, a request with
548 the user-agent ``Mozilla`` and the cookie value ``foo=bar`` will be considered
549 different from a request with the user-agent ``Mozilla`` and the cookie value
550 ``foo=ham``.
552 Because varying on cookie is so common, there's a ``vary_on_cookie``
553 decorator. These two views are equivalent::
555 @vary_on_cookie
556 def my_view(request):
557 # ...
559 @vary_on_headers('Cookie')
560 def my_view(request):
561 # ...
563 The headers you pass to ``vary_on_headers`` are not case sensitive;
564 ``"User-Agent"`` is the same thing as ``"user-agent"``.
566 You can also use a helper function, ``django.utils.cache.patch_vary_headers``,
567 directly. This function sets, or adds to, the ``Vary header``, for example::
569 from django.utils.cache import patch_vary_headers
571 def my_view(request):
572 # ...
573 response = render_to_response('template_name', context)
574 patch_vary_headers(response, ['Cookie'])
575 return response
577 ``patch_vary_headers`` takes an ``HttpResponse`` instance as its first argument
578 and a list/tuple of case-insensitive header names as its second argument.
580 Other Cache Headers
581 -------------------
583 Other problems with caching are the privacy of data and the question of where
584 data should be stored in a cascade of caches.
586 A user usually faces two kinds of caches: his or her own browser cache (a
587 private cache) and his or her provider's cache (a public cache). A public cache
588 is used by multiple users and controlled by someone else. This poses problems
589 with sensitive data--you don't want, say, your bank account number stored in a
590 public cache. So Web applications need a way to tell caches which data is
591 private and which is public.
593 The solution is to indicate a page's cache should be "private." To do this in
594 Django, use the ``cache_control`` view decorator::
596 from django.views.decorators.cache import cache_control
598 @cache_control(private=True)
599 def my_view(request):
600 # ...
602 This decorator takes care of sending out the appropriate HTTP header behind the
603 scenes.
605 There are a few other ways to control cache parameters. For example, HTTP
606 allows applications to do the following:
608 * Define the maximum time a page should be cached.
610 * Specify whether a cache should always check for newer versions, only
611 delivering the cached content when there are no changes. (Some caches
612 might deliver cached content even if the server page changed, simply
613 because the cache copy isn't yet expired.)
615 In Django, use the ``cache_control`` view decorator to specify these cache
616 parameters. In this example, ``cache_control`` tells caches to revalidate the
617 cache on every access and to store cached versions for, at most, 3,600 seconds::
619 from django.views.decorators.cache import cache_control
620 @cache_control(must_revalidate=True, max_age=3600)
621 def my_view(request):
622 ...
624 Any valid ``Cache-Control`` HTTP directive is valid in ``cache_control()``.
625 Here's a full list:
627 * ``public=True``
628 * ``private=True``
629 * ``no_cache=True``
630 * ``no_transform=True``
631 * ``must_revalidate=True``
632 * ``proxy_revalidate=True``
633 * ``max_age=num_seconds``
634 * ``s_maxage=num_seconds``
637 .. admonition:: Tip
639 For explanation of ``Cache-Control`` HTTP directives, see the specification
640 at
642 .. note::
644 The caching middleware already sets the cache header's ``max-age`` with the
645 value of the ``CACHE_MIDDLEWARE_SETTINGS`` setting. If you use a custom
646 ``max_age`` in a ``cache_control`` decorator, the decorator will take
647 precedence, and the header values will be merged correctly.)
649 Other Optimizations
650 ===================
652 Django comes with a few other pieces of middleware that can help optimize your
653 applications' performance:
655 * ``django.middleware.http.ConditionalGetMiddleware`` adds support for
656 modern browsers to conditionally GET responses based on the ``ETag``
657 and ``Last-Modified`` headers.
659 * ``django.middleware.gzip.GZipMiddleware`` compresses responses for all
660 moderns browsers, saving bandwidth and transfer time.
663 ===========================
665 If you use ``CacheMiddleware``, it's important to put it in the right place
666 within the ``MIDDLEWARE_CLASSES`` setting, because the cache middleware needs
667 to know the headers by which to vary the cache storage.
669 Put the ``CacheMiddleware`` after any middlewares that might add something to
670 the ``Vary`` header, including the following:
672 * ``SessionMiddleware``, which adds ``Cookie``
673 * ``GZipMiddleware``, which adds ``Accept-Encoding``
675 What's Next?
676 ============
678 Django ships with a number of "contrib" packages--cool, optional features. We've already covered a few of the: the admin system (Chapter 6) and the session/user framework (Chapter 11).
680 The next chapter covers the rest of the "contributed" subframeworks. There's a
681 lot of cool tools available; you won't want to miss any of them.
Something went wrong with that request. Please try again.