Author: jezdez
Date: 2010-02-23 14:45:28 -0600 (Tue, 23 Feb 2010)
New Revision: 12546

Modified:
   django/trunk/AUTHORS
   django/trunk/django/utils/cache.py
   django/trunk/docs/topics/cache.txt
   django/trunk/tests/regressiontests/cache/tests.py
Log:
Fixed #5691 - Adds the active language to the cache key. Thanks, Antoni Aloy, 
Ramiro Morales and Yann Malet.

Modified: django/trunk/AUTHORS
===================================================================
--- django/trunk/AUTHORS        2010-02-23 20:02:18 UTC (rev 12545)
+++ django/trunk/AUTHORS        2010-02-23 20:45:28 UTC (rev 12546)
@@ -34,6 +34,7 @@
     Marty Alchin <gulop...@gamemusic.org>
     Ahmad Alhashemi <tr...@ahmadh.com>
     Ahmad Al-Ibrahim
+    Antoni Aloy
     Daniel Alves Barbosa de Oliveira Vaz <daniel...@gmail.com>
     AgarFu <hea...@croasanaso.sytes.net>
     Dagur Páll Ammendrup <dag...@gmail.com>
@@ -301,6 +302,7 @@
     Martin Mahner <http://www.mahner.org/>
     Matt McClanahan <http://mmcc.cx/>
     Stanislaus Madueke
+    Yann Malet
     Frantisek Malina <vizual...@vizualbod.com>
     Mike Malone <mjmal...@gmail.com>
     Martin Maney <http://www.chipy.org/Martin_Maney>

Modified: django/trunk/django/utils/cache.py
===================================================================
--- django/trunk/django/utils/cache.py  2010-02-23 20:02:18 UTC (rev 12545)
+++ django/trunk/django/utils/cache.py  2010-02-23 20:45:28 UTC (rev 12546)
@@ -19,16 +19,13 @@
 
 import re
 import time
-try:
-    set
-except NameError:
-    from sets import Set as set   # Python 2.3 fallback
 
 from django.conf import settings
 from django.core.cache import cache
 from django.utils.encoding import smart_str, iri_to_uri
 from django.utils.http import http_date
 from django.utils.hashcompat import md5_constructor
+from django.utils import translation
 from django.http import HttpRequest
 
 cc_delim_re = re.compile(r'\s*,\s*')
@@ -145,13 +142,20 @@
         if value is not None:
             ctx.update(value)
     path = md5_constructor(iri_to_uri(request.path))
-    return 'views.decorators.cache.cache_page.%s.%s.%s' % (
-               key_prefix, path.hexdigest(), ctx.hexdigest())
+    cache_key = 'views.decorators.cache.cache_page.%s.%s.%s' % (
+        key_prefix, path.hexdigest(), ctx.hexdigest())
+    if settings.USE_I18N:
+        cache_key += '.%s' % translation.get_language()
+    return cache_key
 
 def _generate_cache_header_key(key_prefix, request):
     """Returns a cache key for the header cache."""
     path = md5_constructor(iri_to_uri(request.path))
-    return 'views.decorators.cache.cache_header.%s.%s' % (key_prefix, 
path.hexdigest())
+    cache_key = 'views.decorators.cache.cache_header.%s.%s' % (
+        key_prefix, path.hexdigest())
+    if settings.USE_I18N:
+        cache_key += ".%s" % translation.get_language()
+    return cache_key
 
 def get_cache_key(request, key_prefix=None):
     """

Modified: django/trunk/docs/topics/cache.txt
===================================================================
--- django/trunk/docs/topics/cache.txt  2010-02-23 20:02:18 UTC (rev 12545)
+++ django/trunk/docs/topics/cache.txt  2010-02-23 20:45:28 UTC (rev 12546)
@@ -320,6 +320,13 @@
 the ``never_cache`` decorator). See the `using other headers`__ section for
 more on these decorators.
 
+.. versionadded:: 1.2
+
+If :setting:`USE_I18N` is set to ``True`` then the generated cache key will
+include the name of the currently active :term:`language<language code>`.
+This allows you to easily cache multilingual sites without having to create
+the cache key yourself.
+
 __ `Controlling cache: Using other headers`_
 
 The per-view cache

Modified: django/trunk/tests/regressiontests/cache/tests.py
===================================================================
--- django/trunk/tests/regressiontests/cache/tests.py   2010-02-23 20:02:18 UTC 
(rev 12545)
+++ django/trunk/tests/regressiontests/cache/tests.py   2010-02-23 20:45:28 UTC 
(rev 12546)
@@ -14,6 +14,8 @@
 from django.core.cache import get_cache
 from django.core.cache.backends.base import InvalidCacheBackendError
 from django.http import HttpResponse, HttpRequest
+from django.middleware.cache import FetchFromCacheMiddleware, 
UpdateCacheMiddleware
+from django.utils import translation
 from django.utils.cache import patch_vary_headers, get_cache_key, 
learn_cache_key
 from django.utils.hashcompat import md5_constructor
 from regressiontests.cache.models import Poll, expensive_calculation
@@ -401,12 +403,15 @@
         self.path = '/cache/test/'
         self.old_settings_key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
         self.old_middleware_seconds = settings.CACHE_MIDDLEWARE_SECONDS
+        self.orig_use_i18n = settings.USE_I18N
         settings.CACHE_MIDDLEWARE_KEY_PREFIX = 'settingsprefix'
         settings.CACHE_MIDDLEWARE_SECONDS = 1
+        settings.USE_I18N = False
 
     def tearDown(self):
         settings.CACHE_MIDDLEWARE_KEY_PREFIX = self.old_settings_key_prefix
         settings.CACHE_MIDDLEWARE_SECONDS = self.old_middleware_seconds
+        settings.USE_I18N = self.orig_use_i18n
 
     def _get_request(self, path):
         request = HttpRequest()
@@ -458,5 +463,101 @@
         learn_cache_key(request, response)
         self.assertEqual(get_cache_key(request), 
'views.decorators.cache.cache_page.settingsprefix.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
 
+class CacheI18nTest(unittest.TestCase):
+
+    def setUp(self):
+        self.orig_cache_middleware_seconds = settings.CACHE_MIDDLEWARE_SECONDS
+        self.orig_cache_middleware_key_prefix = 
settings.CACHE_MIDDLEWARE_KEY_PREFIX
+        self.orig_cache_backend = settings.CACHE_BACKEND
+        self.orig_use_i18n = settings.USE_I18N
+        self.orig_languages =  settings.LANGUAGES
+        settings.LANGUAGES = (
+                ('en', 'English'),
+                ('es', 'Spanish'),
+        )
+        settings.CACHE_MIDDLEWARE_KEY_PREFIX = 'settingsprefix'
+        settings.CACHE_MIDDLEWARE_SECONDS
+        self.path = '/cache/test/'
+
+    def tearDown(self):
+        settings.CACHE_MIDDLEWARE_SECONDS = self.orig_cache_middleware_seconds
+        settings.CACHE_MIDDLEWARE_KEY_PREFIX = 
self.orig_cache_middleware_key_prefix
+        settings.CACHE_BACKEND = self.orig_cache_backend
+        settings.USE_I18N = self.orig_use_i18n
+        settings.LANGUAGES = self.orig_languages
+        translation.deactivate()
+
+    def _get_request(self):
+        request = HttpRequest()
+        request.META = {
+            'SERVER_NAME': 'testserver',
+            'SERVER_PORT': 80,
+        }
+        request.path = request.path_info = self.path
+        return request
+
+    def _get_request_cache(self):
+        request = HttpRequest()
+        request.META = {
+            'SERVER_NAME': 'testserver',
+            'SERVER_PORT': 80,
+        }
+        request.path = request.path_info = self.path
+        request._cache_update_cache = True
+        request.method = 'GET'
+        request.session = {}
+        return request
+
+    def test_cache_key_i18n(self):
+        settings.USE_I18N = True
+        request = self._get_request()
+        lang = translation.get_language()
+        response = HttpResponse()
+        key = learn_cache_key(request, response)
+        self.assertTrue(key.endswith(lang), "Cache keys should include the 
language name when i18n is active")
+        key2 = get_cache_key(request)
+        self.assertEqual(key, key2)
+
+    def test_cache_key_no_i18n (self):
+        settings.USE_I18N = False
+        request = self._get_request()
+        lang = translation.get_language()
+        response = HttpResponse()
+        key = learn_cache_key(request, response)
+        self.assertFalse(key.endswith(lang), "Cache keys shouldn't include the 
language name when i18n is inactive")
+
+    def test_middleware(self):
+        def set_cache(request, lang, msg):
+            translation.activate(lang)
+            response = HttpResponse()
+            response.content= msg
+            return UpdateCacheMiddleware().process_response(request, response)
+
+        settings.CACHE_MIDDLEWARE_SECONDS = 60
+        settings.CACHE_MIDDLEWARE_KEY_PREFIX="test"
+        settings.CACHE_BACKEND='locmem:///'
+        settings.USE_I18N = True
+        en_message ="Hello world!"
+        es_message ="Hola mundo!"
+
+        request = self._get_request_cache()
+        set_cache(request, 'en', en_message)
+        get_cache_data = FetchFromCacheMiddleware().process_request(request)
+        # Check that we can recover the cache
+        self.assertNotEqual(get_cache_data.content, None)
+        self.assertEqual(en_message, get_cache_data.content)
+        # change the session language and set content
+        request = self._get_request_cache()
+        set_cache(request, 'es', es_message)
+        # change again the language
+        translation.activate('en')
+        # retrieve the content from cache
+        get_cache_data = FetchFromCacheMiddleware().process_request(request)
+        self.assertEqual(get_cache_data.content, en_message)
+        # change again the language
+        translation.activate('es')
+        get_cache_data = FetchFromCacheMiddleware().process_request(request)
+        self.assertEqual(get_cache_data.content, es_message)
+
 if __name__ == '__main__':
     unittest.main()

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-upda...@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to