17 "Accept-language" header. |
17 "Accept-language" header. |
18 """ |
18 """ |
19 |
19 |
20 import re |
20 import re |
21 import time |
21 import time |
22 try: |
|
23 set |
|
24 except NameError: |
|
25 from sets import Set as set # Python 2.3 fallback |
|
26 |
22 |
27 from django.conf import settings |
23 from django.conf import settings |
28 from django.core.cache import cache |
24 from django.core.cache import cache |
29 from django.utils.encoding import smart_str, iri_to_uri |
25 from django.utils.encoding import smart_str, iri_to_uri |
30 from django.utils.http import http_date |
26 from django.utils.http import http_date |
31 from django.utils.hashcompat import md5_constructor |
27 from django.utils.hashcompat import md5_constructor |
|
28 from django.utils.translation import get_language |
32 from django.http import HttpRequest |
29 from django.http import HttpRequest |
33 |
30 |
34 cc_delim_re = re.compile(r'\s*,\s*') |
31 cc_delim_re = re.compile(r'\s*,\s*') |
35 |
32 |
36 def patch_cache_control(response, **kwargs): |
33 def patch_cache_control(response, **kwargs): |
135 existing_headers = set([header.lower() for header in vary_headers]) |
132 existing_headers = set([header.lower() for header in vary_headers]) |
136 additional_headers = [newheader for newheader in newheaders |
133 additional_headers = [newheader for newheader in newheaders |
137 if newheader.lower() not in existing_headers] |
134 if newheader.lower() not in existing_headers] |
138 response['Vary'] = ', '.join(vary_headers + additional_headers) |
135 response['Vary'] = ', '.join(vary_headers + additional_headers) |
139 |
136 |
|
137 def _i18n_cache_key_suffix(request, cache_key): |
|
138 """If enabled, returns the cache key ending with a locale.""" |
|
139 if settings.USE_I18N: |
|
140 # first check if LocaleMiddleware or another middleware added |
|
141 # LANGUAGE_CODE to request, then fall back to the active language |
|
142 # which in turn can also fall back to settings.LANGUAGE_CODE |
|
143 cache_key += '.%s' % getattr(request, 'LANGUAGE_CODE', get_language()) |
|
144 return cache_key |
|
145 |
140 def _generate_cache_key(request, headerlist, key_prefix): |
146 def _generate_cache_key(request, headerlist, key_prefix): |
141 """Returns a cache key from the headers given in the header list.""" |
147 """Returns a cache key from the headers given in the header list.""" |
142 ctx = md5_constructor() |
148 ctx = md5_constructor() |
143 for header in headerlist: |
149 for header in headerlist: |
144 value = request.META.get(header, None) |
150 value = request.META.get(header, None) |
145 if value is not None: |
151 if value is not None: |
146 ctx.update(value) |
152 ctx.update(value) |
147 path = md5_constructor(iri_to_uri(request.path)) |
153 path = md5_constructor(iri_to_uri(request.path)) |
148 return 'views.decorators.cache.cache_page.%s.%s.%s' % ( |
154 cache_key = 'views.decorators.cache.cache_page.%s.%s.%s' % ( |
149 key_prefix, path.hexdigest(), ctx.hexdigest()) |
155 key_prefix, path.hexdigest(), ctx.hexdigest()) |
|
156 return _i18n_cache_key_suffix(request, cache_key) |
150 |
157 |
151 def _generate_cache_header_key(key_prefix, request): |
158 def _generate_cache_header_key(key_prefix, request): |
152 """Returns a cache key for the header cache.""" |
159 """Returns a cache key for the header cache.""" |
153 path = md5_constructor(iri_to_uri(request.path)) |
160 path = md5_constructor(iri_to_uri(request.path)) |
154 return 'views.decorators.cache.cache_header.%s.%s' % (key_prefix, path.hexdigest()) |
161 cache_key = 'views.decorators.cache.cache_header.%s.%s' % ( |
|
162 key_prefix, path.hexdigest()) |
|
163 return _i18n_cache_key_suffix(request, cache_key) |
155 |
164 |
156 def get_cache_key(request, key_prefix=None): |
165 def get_cache_key(request, key_prefix=None): |
157 """ |
166 """ |
158 Returns a cache key based on the request path. It can be used in the |
167 Returns a cache key based on the request path. It can be used in the |
159 request phase because it pulls the list of headers to take into account |
168 request phase because it pulls the list of headers to take into account |