Ticket #5691: patch_cache_i18n.patch
File patch_cache_i18n.patch, 14.5 KB (added by , 16 years ago) |
---|
-
django/utils/cache.py
29 29 from django.utils.encoding import smart_str, iri_to_uri 30 30 from django.utils.http import http_date 31 31 from django.utils.hashcompat import md5_constructor 32 from django.utils import translation 32 33 33 34 cc_delim_re = re.compile(r'\s*,\s*') 34 35 … … 136 137 if newheader.lower() not in existing_headers] 137 138 response['Vary'] = ', '.join(vary_headers + additional_headers) 138 139 139 def _generate_cache_key(request, headerlist, key_prefix): 140 def _generate_cache_key(request, headerlist, key_prefix): 140 141 """Returns a cache key from the headers given in the header list.""" 141 142 ctx = md5_constructor() 142 143 for header in headerlist: 143 144 value = request.META.get(header, None) 144 145 if value is not None: 145 146 ctx.update(value) 146 return'views.decorators.cache.cache_page.%s.%s.%s' % (147 cache_key = 'views.decorators.cache.cache_page.%s.%s.%s' % ( 147 148 key_prefix, iri_to_uri(request.path), ctx.hexdigest()) 148 149 150 if settings.USE_I18N: 151 cache_key += ".%s" % translation.get_language() 152 return cache_key 153 154 149 155 def get_cache_key(request, key_prefix=None): 150 156 """ 151 157 Returns a cache key based on the request path. It can be used in the … … 155 161 156 162 If there is no headerlist stored, the page needs to be rebuilt, so this 157 163 function returns None. 158 """ 164 """ 159 165 if key_prefix is None: 160 166 key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX 161 167 cache_key = 'views.decorators.cache.cache_header.%s.%s' % ( 162 168 key_prefix, iri_to_uri(request.path)) 169 if settings.USE_I18N: 170 cache_key += ".%s" % translation.get_language() 171 163 172 headerlist = cache.get(cache_key, None) 164 173 if headerlist is not None: 165 174 return _generate_cache_key(request, headerlist, key_prefix) … … 183 192 key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX 184 193 if cache_timeout is None: 185 194 cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS 195 186 196 cache_key = 'views.decorators.cache.cache_header.%s.%s' % ( 187 key_prefix, iri_to_uri(request.path)) 197 key_prefix, iri_to_uri(request.path)) 198 if settings.USE_I18N: 199 cache_key += ".%s" % translation.get_language() 200 188 201 if response.has_header('Vary'): 189 202 headerlist = ['HTTP_'+header.upper().replace('-', '_') 190 203 for header in cc_delim_re.split(response['Vary'])] -
django/middleware/cache.py
68 68 69 69 def process_response(self, request, response): 70 70 """Sets the cache, if needed.""" 71 71 72 if not hasattr(request, '_cache_update_cache') or not request._cache_update_cache: 72 73 # We don't need to update the cache, just return. 73 74 return response -
tests/regressiontests/cachei18n/views.py
Property changes on: tests/regressiontests/cachei18n ___________________________________________________________________ Added: svn:ignore + __init__.pyc
1 #/usr/bin/env python 2 # -*- coding: UTF-8 -*- 3 from django.shortcuts import render_to_response 4 from django.views.decorators.cache import cache_page 5 6 RECORDS_PER_PAGE=2 7 VISIBLE_PAGES=3 8 9 @cache_page(3600) 10 def app_index(request, page=1): 11 "Home page with pagination. Adapted to the trunk version of paginator" 12 data['content'] = "this is a test" 13 response = render_to_response('agenda/index.html',data) 14 return response 15 16 17 18 -
tests/regressiontests/cachei18n/__init__.py
1 __author__="aaloy" 2 __date__ ="$21/11/2008 09:55:21$" 3 No newline at end of file -
tests/regressiontests/cachei18n/settings.py
1 # Django settings for test2 project. 2 3 DEBUG = True 4 TEMPLATE_DEBUG = DEBUG 5 6 ADMINS = ( 7 # ('Your Name', 'your_email@domain.com'), 8 ) 9 10 MANAGERS = ADMINS 11 12 DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 13 DATABASE_NAME = '/tmp/test.sqlite' # Or path to database file if using sqlite3. 14 DATABASE_USER = '' # Not used with sqlite3. 15 DATABASE_PASSWORD = '' # Not used with sqlite3. 16 DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. 17 DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. 18 19 # Local time zone for this installation. Choices can be found here: 20 # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 21 # although not all choices may be available on all operating systems. 22 # If running in a Windows environment this must be set to the same as your 23 # system time zone. 24 TIME_ZONE = 'America/Chicago' 25 26 # Language code for this installation. All choices can be found here: 27 # http://www.i18nguy.com/unicode/language-identifiers.html 28 LANGUAGE_CODE = 'en-us' 29 30 SITE_ID = 1 31 32 # If you set this to False, Django will make some optimizations so as not 33 # to load the internationalization machinery. 34 USE_I18N = True 35 36 # Absolute path to the directory that holds media. 37 # Example: "/home/media/media.lawrence.com/" 38 MEDIA_ROOT = '' 39 40 # URL that handles the media served from MEDIA_ROOT. Make sure to use a 41 # trailing slash if there is a path component (optional in other cases). 42 # Examples: "http://media.lawrence.com", "http://example.com/media/" 43 MEDIA_URL = '' 44 45 # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a 46 # trailing slash. 47 # Examples: "http://foo.com/media/", "/media/". 48 ADMIN_MEDIA_PREFIX = '/media/' 49 50 # Make this unique, and don't share it with anybody. 51 SECRET_KEY = 'il_uk6kwtuj4&(n$o*u-2x$k+f54r02)*zw+b+sx_g%puw6@b(' 52 53 # List of callables that know how to import templates from various sources. 54 TEMPLATE_LOADERS = ( 55 'django.template.loaders.filesystem.load_template_source', 56 'django.template.loaders.app_directories.load_template_source', 57 # 'django.template.loaders.eggs.load_template_source', 58 ) 59 60 MIDDLEWARE_CLASSES = ( 61 'django.middleware.common.CommonMiddleware', 62 'django.contrib.sessions.middleware.SessionMiddleware', 63 'django.middleware.locale.LocaleMiddleware', 64 'django.contrib.auth.middleware.AuthenticationMiddleware', 65 ) 66 67 ROOT_URLCONF = 'test2.urls' 68 69 TEMPLATE_DIRS = ( 70 # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". 71 # Always use forward slashes, even on Windows. 72 # Don't forget to use absolute paths, not relative paths. 73 ) 74 75 INSTALLED_APPS = ( 76 'django.contrib.auth', 77 'django.contrib.contenttypes', 78 'django.contrib.sessions', 79 'django.contrib.sites', 80 ) 81 82 LANGUAGES = ( 83 ('en', 'English'), 84 ('es', 'Spanish'), 85 ) 86 -
tests/regressiontests/cachei18n/tests.py
1 # -*- coding: UTF-8 -*- 2 3 from django.core.cache import cache 4 from django.core.cache import get_cache 5 from django.core.cache.backends.filebased import CacheClass as FileCache 6 from django.http import HttpRequest 7 from django.http import HttpResponse 8 from django.utils import cache 9 from django.utils import translation 10 11 import shutil 12 import tempfile 13 import unittest 14 from django.conf import settings 15 from django.middleware.cache import FetchFromCacheMiddleware, UpdateCacheMiddleware 16 17 18 19 20 class Cache(unittest.TestCase): 21 def setUp(self): 22 # Special-case the file cache so we can clean up after ourselves. 23 if isinstance(cache, FileCache): 24 self.cache_dir = tempfile.mkdtemp() 25 self.cache = get_cache("file:///%s" % self.cache_dir) 26 else: 27 self.cache_dir = None 28 self.cache = cache 29 settings.LANGUAGES = ( 30 ('en', 'English'), 31 ('es', 'Spanish'), 32 ) 33 34 def tearDown(self): 35 if self.cache_dir is not None: 36 shutil.rmtree(self.cache_dir) 37 38 def _get_request(self): 39 request = HttpRequest() 40 request.META = { 41 'SERVER_NAME': 'testserver', 42 'SERVER_PORT': 80, 43 } 44 request.path = request.path_info = "/agenda/index/" 45 return request 46 47 def _get_request_cache(self): 48 request = HttpRequest() 49 request.META = { 50 'SERVER_NAME': 'testserver', 51 'SERVER_PORT': 80, 52 } 53 request.path = request.path_info = "/agenda/index/" 54 request._cache_update_cache = True 55 request.method = 'GET' 56 request.session = {} 57 return request 58 59 60 61 def test_cache_key_i18n(self): 62 settings.USE_I18N = True 63 request = self._get_request() 64 lang = translation.get_language() 65 response = HttpResponse() 66 key = cache.learn_cache_key(request, response) 67 self.assertTrue(key.endswith(lang), "Keys does not use the language") 68 key2 = cache.get_cache_key(request) 69 self.assertEqual(key, key2) 70 71 def test_cache_key_not_i18n (self): 72 settings.USE_I18N = False 73 request = self._get_request() 74 lang = translation.get_language() 75 response = HttpResponse() 76 key = cache.learn_cache_key(request, response) 77 self.assertFalse(key.endswith(lang), "Keys does not use the language") 78 79 def test_middleware(self): 80 81 def set_cache(request, lang, msg): 82 translation.activate(lang) 83 response = HttpResponse() 84 response.content= msg 85 return UpdateCacheMiddleware().process_response(request, response) 86 87 settings.CACHE_MIDDLEWARE_SECONDS = 60 88 settings.CACHE_MIDDLEWARE_KEY_PREFIX="test" 89 settings.CACHE_BACKEND='locmem:///' 90 settings.USE_I18N = True 91 en_message ="Hello world!" 92 es_message ="Hola mundo!" 93 94 request = self._get_request_cache() 95 set_cache(request, 'en', en_message) 96 get_cache_data = FetchFromCacheMiddleware().process_request(request) 97 # Check that we can recover the cache 98 self.assertNotEqual(get_cache_data.content, None) 99 self.assertEqual(en_message, get_cache_data.content) 100 # change the session language and set content 101 request = self._get_request_cache() 102 set_cache(request, 'es', es_message) 103 # change again the language 104 translation.activate('en') 105 # retrieve the content from cache 106 get_cache_data = FetchFromCacheMiddleware().process_request(request) 107 self.assertEqual(get_cache_data.content, en_message) 108 # change again the language 109 translation.activate('es') 110 get_cache_data = FetchFromCacheMiddleware().process_request(request) 111 self.assertEqual(get_cache_data.content, es_message) 112 113 114 if __name__ == '__main__': 115 unittest.main() -
tests/regressiontests/cachei18n/models.py
1 # -*- coding: UTF-8 -*- 2 __doc__ = """Defines de application model""" 3 4 from django.db import models 5 6 7 class Person (models.Model): 8 "Defines the model for the person entity" 9 first_name = models.CharField(max_length=30) 10 last_name = models.CharField(max_length=30) 11 phone = models.CharField(max_length=20) 12 age = models.IntegerField() 13 comments = models.TextField() 14 15 def __unicode__(self): 16 return u'%s %s' % (self.first_name, self.last_name) 17 18 -
tests/regressiontests/cachei18n/urls.py
1 from django.conf.urls.defaults import * 2 from django.conf import settings 3 from django.contrib import admin 4 from django.views.generic.simple import direct_to_template 5 6 admin.autodiscover() 7 8 urlpatterns = patterns('', 9 # our agenda application 10 (r'^$',direct_to_template, {'template': 'index.html'}), 11 (r'^appindex/$', 'views.appindex') 12 # Administration 13 (r'^admin/doc/', include('django.contrib.admindocs.urls')), 14 (r'^admin/(.*)', admin.site.root), 15 ) 16 17 18 # We're going to use the Django server in development, so we'll server 19 # also the estatic content. 20 if settings.DEBUG: 21 urlpatterns += patterns('', 22 (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root':'./media/'}), 23 ) 24 25 -
tests/regressiontests/cachei18n/templates/agenda/index.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <title>agenda title</title> 5 <link rel="stylesheet" type="text/css" href="/media/css/paginator.css" /> 6 </head> 7 <body> 8 <h1>{{ content }}</h1> 9 </body> 10 </html> -
tests/regressiontests/cachei18n/templates/index.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <title>test title</title> 5 </head> 6 <body> 7 <body> 8 <p>This is a test page for cache purposes</p> 9 <p><strong>Menu</strong></p> 10 </body> 11 </html>