Ticket #15499: allow-cache-control-private-override-3.diff

File allow-cache-control-private-override-3.diff, 4.6 KB (added by Andreas Sommer, 13 years ago)

New patch to integrate into recent trunk

  • django/utils/cache.py

     
    6767    if 'max-age' in cc and 'max_age' in kwargs:
    6868        kwargs['max_age'] = min(cc['max-age'], kwargs['max_age'])
    6969
     70    # Allow overriding private caching and vice versa
     71    if 'private' in cc and 'public' in kwargs:
     72        del cc['private']
     73    elif 'public' in cc and 'private' in kwargs:
     74        del cc['public']
     75
    7076    for (k, v) in kwargs.items():
    7177        cc[k.replace('_', '-')] = v
    7278    cc = ', '.join([dictvalue(el) for el in cc.items()])
  • docs/topics/cache.txt

     
    10621062This decorator takes care of sending out the appropriate HTTP header behind the
    10631063scenes.
    10641064
     1065Note that the cache control settings "private" and "public" are mutually
     1066exclusive. The decorator ensures that the "public" directive is removed if
     1067"private" should be set (and vice versa). An example use of the two directives
     1068would be a blog site that offers both private and public entries. Public
     1069entries may be cached on any shared cache. The following code uses
     1070``patch_cache_control``, the manual way to modify the cache control header
     1071(it is internally called by the ``cache_control`` decorator)::
     1072
     1073    from django.views.decorators.cache import patch_cache_control
     1074    from django.views.decorators.vary import vary_on_cookie
     1075
     1076    @vary_on_cookie
     1077    def list_blog_entries_view(request):
     1078        if request.user.is_anonymous():
     1079            response = render_only_public_entries()
     1080            patch_cache_control(response, public=True)
     1081        else:
     1082            response = render_private_and_public_entries(request.user)
     1083            patch_cache_control(response, private=True)
     1084
     1085        return response
     1086
    10651087There are a few other ways to control cache parameters. For example, HTTP
    10661088allows applications to do the following:
    10671089
  • tests/regressiontests/cache/tests.py

     
    55
    66import hashlib
    77import os
     8import re
    89import tempfile
    910import time
    1011import warnings
     
    1920from django.test.utils import get_warnings_state, restore_warnings_state
    2021from django.utils import translation
    2122from django.utils import unittest
    22 from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key
     23from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key, patch_cache_control
    2324from django.views.decorators.cache import cache_page
    2425
    2526from regressiontests.cache.models import Poll, expensive_calculation
     
    980981        learn_cache_key(request, response)
    981982        self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.HEAD.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
    982983
     984    def test_patch_cache_control(self):
     985        tests = (
     986            # Initial Cache-Control, kwargs to patch_cache_control, expected Cache-Control parts
     987            (None, {"private" : True}, set(['private'])),
     988
     989            # Test whether private/public attributes are mutually exclusive
     990            ('private', {"private" : True}, set(['private'])),
     991            ('private', {"public" : True}, set(['public'])),
     992            ('public', {"private" : True}, set(['private'])),
     993            ('must-revalidate,max-age=60,private', {"public" : True}, set(['must-revalidate', 'max-age=60', 'public'])),
     994            ('must-revalidate,max-age=60,public', {"private" : True}, set(['must-revalidate', 'max-age=60', 'private'])),
     995
     996            ('public', {"public" : True}, set(['public'])),
     997            ('private', {"private" : True}, set(['private'])),
     998
     999            ('must-revalidate,max-age=60', {"public" : True}, set(['must-revalidate', 'max-age=60', 'public'])),
     1000        )
     1001
     1002        cc_delim_re = re.compile(r'\s*,\s*')
     1003
     1004        for initial_cc, newheaders, expected_cc in tests:
     1005            response = HttpResponse()
     1006            if initial_cc is not None:
     1007                response['Cache-Control'] = initial_cc
     1008            patch_cache_control(response, **newheaders)
     1009            parts = set(cc_delim_re.split(response['Cache-Control']))
     1010            self.assertEqual(parts, expected_cc)
     1011
    9831012class PrefixedCacheUtils(CacheUtils):
    9841013    def setUp(self):
    9851014        super(PrefixedCacheUtils, self).setUp()
Back to Top