summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2011-01-24 06:36:31 +0000
committerRussell Keith-Magee <russell@keith-magee.com>2011-01-24 06:36:31 +0000
commitfe581013b03b3dd38f4893bb5e9dc9695af25d71 (patch)
tree5ac4b726cb04aac1bc80a49e1814aa0d27c00f38
parent4849ebb017362f38cf281409e227bc755cc0eca6 (diff)
Fixed #15144 -- Corrected some problems with the Cache middleware when used with multiple cache settings. Thanks to Jim Dalton for the report, and to Jim and Joshua Ginsberg for the work on the patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@15285 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--AUTHORS1
-rw-r--r--django/core/cache/__init__.py1
-rw-r--r--django/middleware/cache.py20
-rw-r--r--tests/regressiontests/cache/tests.py70
4 files changed, 76 insertions, 16 deletions
diff --git a/AUTHORS b/AUTHORS
index ffcc34d5dd..ceb5f1a7c7 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -129,6 +129,7 @@ answer newbie questions, and generally made Django that much better:
Jure Cuhalev <gandalf@owca.info>
John D'Agostino <john.dagostino@gmail.com>
dackze+django@gmail.com
+ Jim Dalton <jim.dalton@gmail.com>
Mihai Damian <yang_damian@yahoo.com>
David Danier <goliath.mailinglist@gmx.de>
Dirk Datzert <dummy@habmalnefrage.de>
diff --git a/django/core/cache/__init__.py b/django/core/cache/__init__.py
index a30aa390ac..ced9875b07 100644
--- a/django/core/cache/__init__.py
+++ b/django/core/cache/__init__.py
@@ -110,6 +110,7 @@ def parse_backend_conf(backend, **kwargs):
conf = settings.CACHES.get(backend, None)
if conf is not None:
args = conf.copy()
+ args.update(kwargs)
backend = args.pop('BACKEND')
location = args.pop('LOCATION', '')
return backend, location, args
diff --git a/django/middleware/cache.py b/django/middleware/cache.py
index 31a8147eec..907edbb16f 100644
--- a/django/middleware/cache.py
+++ b/django/middleware/cache.py
@@ -65,7 +65,8 @@ class UpdateCacheMiddleware(object):
self.cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS
self.key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
self.cache_anonymous_only = getattr(settings, 'CACHE_MIDDLEWARE_ANONYMOUS_ONLY', False)
- self.cache = get_cache(settings.CACHE_MIDDLEWARE_ALIAS)
+ self.cache_alias = settings.CACHE_MIDDLEWARE_ALIAS
+ self.cache = get_cache(self.cache_alias)
def process_response(self, request, response):
"""Sets the cache, if needed."""
@@ -101,7 +102,8 @@ class FetchFromCacheMiddleware(object):
self.cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS
self.key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
self.cache_anonymous_only = getattr(settings, 'CACHE_MIDDLEWARE_ANONYMOUS_ONLY', False)
- self.cache = get_cache(settings.CACHE_MIDDLEWARE_ALIAS)
+ self.cache_alias = settings.CACHE_MIDDLEWARE_ALIAS
+ self.cache = get_cache(self.cache_alias)
def process_request(self, request):
"""
@@ -152,8 +154,9 @@ class CacheMiddleware(UpdateCacheMiddleware, FetchFromCacheMiddleware):
# we need to use middleware defaults.
cache_kwargs = {}
+
try:
- self.key_prefix = kwargs.get('key_prefix')
+ self.key_prefix = kwargs['key_prefix']
if self.key_prefix is not None:
cache_kwargs['KEY_PREFIX'] = self.key_prefix
else:
@@ -161,14 +164,15 @@ class CacheMiddleware(UpdateCacheMiddleware, FetchFromCacheMiddleware):
except KeyError:
self.key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
cache_kwargs['KEY_PREFIX'] = self.key_prefix
+
try:
- cache_alias = kwargs.get('cache_alias')
- if cache_alias is None:
- cache_alias = DEFAULT_CACHE_ALIAS
+ self.cache_alias = kwargs['cache_alias']
+ if self.cache_alias is None:
+ self.cache_alias = DEFAULT_CACHE_ALIAS
if cache_timeout is not None:
cache_kwargs['TIMEOUT'] = cache_timeout
except KeyError:
- cache_alias = settings.CACHE_MIDDLEWARE_ALIAS
+ self.cache_alias = settings.CACHE_MIDDLEWARE_ALIAS
if cache_timeout is None:
cache_kwargs['TIMEOUT'] = settings.CACHE_MIDDLEWARE_SECONDS
else:
@@ -179,5 +183,5 @@ class CacheMiddleware(UpdateCacheMiddleware, FetchFromCacheMiddleware):
else:
self.cache_anonymous_only = cache_anonymous_only
- self.cache = get_cache(cache_alias, **cache_kwargs)
+ self.cache = get_cache(self.cache_alias, **cache_kwargs)
self.cache_timeout = self.cache.default_timeout
diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py
index f2cfcb37da..1a1e2438bd 100644
--- a/tests/regressiontests/cache/tests.py
+++ b/tests/regressiontests/cache/tests.py
@@ -1133,10 +1133,14 @@ class CacheMiddlewareTest(unittest.TestCase):
def setUp(self):
self.orig_cache_middleware_alias = settings.CACHE_MIDDLEWARE_ALIAS
self.orig_cache_middleware_key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
+ self.orig_cache_middleware_seconds = settings.CACHE_MIDDLEWARE_SECONDS
+ self.orig_cache_middleware_anonymous_only = getattr(settings, 'CACHE_MIDDLEWARE_ANONYMOUS_ONLY', False)
self.orig_caches = settings.CACHES
settings.CACHE_MIDDLEWARE_ALIAS = 'other'
settings.CACHE_MIDDLEWARE_KEY_PREFIX = 'middlewareprefix'
+ settings.CACHE_MIDDLEWARE_SECONDS = 30
+ settings.CACHE_MIDDLEWARE_ANONYMOUS_ONLY = False
settings.CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
@@ -1151,8 +1155,42 @@ class CacheMiddlewareTest(unittest.TestCase):
def tearDown(self):
settings.CACHE_MIDDLEWARE_ALIAS = self.orig_cache_middleware_alias
settings.CACHE_MIDDLEWARE_KEY_PREFIX = self.orig_cache_middleware_key_prefix
+ settings.CACHE_MIDDLEWARE_SECONDS = self.orig_cache_middleware_seconds
+ settings.CACHE_MIDDLEWARE_ANONYMOUS_ONLY = self.orig_cache_middleware_anonymous_only
settings.CACHES = self.orig_caches
+ def test_constructor(self):
+ """
+ Ensure the constructor is correctly distinguishing between usage of CacheMiddleware as
+ Middleware vs. usage of CacheMiddleware as view decorator and setting attributes
+ appropriately.
+ """
+ # If no arguments are passed in construction, it's being used as middleware.
+ middleware = CacheMiddleware()
+
+ # Now test object attributes against values defined in setUp above
+ self.assertEquals(middleware.cache_timeout, 30)
+ self.assertEquals(middleware.key_prefix, 'middlewareprefix')
+ self.assertEquals(middleware.cache_alias, 'other')
+ self.assertEquals(middleware.cache_anonymous_only, False)
+
+ # If arguments are being passed in construction, it's being used as a decorator.
+ # First, test with "defaults":
+ as_view_decorator = CacheMiddleware(cache_alias=None, key_prefix=None)
+
+ self.assertEquals(as_view_decorator.cache_timeout, 300) # Timeout value for 'default' cache, i.e. 300
+ self.assertEquals(as_view_decorator.key_prefix, '')
+ self.assertEquals(as_view_decorator.cache_alias, 'default') # Value of DEFAULT_CACHE_ALIAS from django.core.cache
+ self.assertEquals(as_view_decorator.cache_anonymous_only, False)
+
+ # Next, test with custom values:
+ as_view_decorator_with_custom = CacheMiddleware(cache_anonymous_only=True, cache_timeout=60, cache_alias='other', key_prefix='foo')
+
+ self.assertEquals(as_view_decorator_with_custom.cache_timeout, 60)
+ self.assertEquals(as_view_decorator_with_custom.key_prefix, 'foo')
+ self.assertEquals(as_view_decorator_with_custom.cache_alias, 'other')
+ self.assertEquals(as_view_decorator_with_custom.cache_anonymous_only, True)
+
def test_middleware(self):
def view(request, value):
return HttpResponse('Hello World %s' % value)
@@ -1201,6 +1239,7 @@ class CacheMiddlewareTest(unittest.TestCase):
other_view = cache_page(cache='other')(view)
other_with_prefix_view = cache_page(cache='other', key_prefix='prefix2')(view)
+ other_with_timeout_view = cache_page(4, cache='other', key_prefix='prefix3')(view)
factory = RequestFactory()
request = factory.get('/view/')
@@ -1241,33 +1280,48 @@ class CacheMiddlewareTest(unittest.TestCase):
response = other_with_prefix_view(request, '9')
self.assertEquals(response.content, 'Hello World 9')
+ # Request from the alternate cache with a new prefix and a custom timeout
+ response = other_with_timeout_view(request, '10')
+ self.assertEquals(response.content, 'Hello World 10')
+
# But if we wait a couple of seconds...
time.sleep(2)
# ... the default cache will still hit
cache = get_cache('default')
- response = default_view(request, '10')
+ response = default_view(request, '11')
self.assertEquals(response.content, 'Hello World 1')
# ... the default cache with a prefix will still hit
- response = default_with_prefix_view(request, '11')
+ response = default_with_prefix_view(request, '12')
self.assertEquals(response.content, 'Hello World 4')
# ... the explicit default cache will still hit
- response = explicit_default_view(request, '12')
+ response = explicit_default_view(request, '13')
self.assertEquals(response.content, 'Hello World 1')
# ... the explicit default cache with a prefix will still hit
- response = explicit_default_with_prefix_view(request, '13')
+ response = explicit_default_with_prefix_view(request, '14')
self.assertEquals(response.content, 'Hello World 4')
# .. but a rapidly expiring cache won't hit
- response = other_view(request, '14')
- self.assertEquals(response.content, 'Hello World 14')
+ response = other_view(request, '15')
+ self.assertEquals(response.content, 'Hello World 15')
# .. even if it has a prefix
- response = other_with_prefix_view(request, '15')
- self.assertEquals(response.content, 'Hello World 15')
+ response = other_with_prefix_view(request, '16')
+ self.assertEquals(response.content, 'Hello World 16')
+
+ # ... but a view with a custom timeout will still hit
+ response = other_with_timeout_view(request, '17')
+ self.assertEquals(response.content, 'Hello World 10')
+
+ # And if we wait a few more seconds
+ time.sleep(2)
+
+ # the custom timeouot cache will miss
+ response = other_with_timeout_view(request, '18')
+ self.assertEquals(response.content, 'Hello World 18')
if __name__ == '__main__':
unittest.main()