diff --git a/django/middleware/cache.py b/django/middleware/cache.py index 7789c3492c6..6302a172c75 100644 --- a/django/middleware/cache.py +++ b/django/middleware/cache.py @@ -50,7 +50,7 @@ More details about how the caching works: from django.conf import settings from django.core.cache import get_cache, DEFAULT_CACHE_ALIAS -from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers, get_max_age, has_vary_header +from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers, get_max_age class UpdateCacheMiddleware(object): @@ -69,10 +69,19 @@ class UpdateCacheMiddleware(object): self.cache_alias = settings.CACHE_MIDDLEWARE_ALIAS self.cache = get_cache(self.cache_alias) + def _session_accessed(self, request): + try: + return request.session.accessed + except AttributeError: + return False + def _should_update_cache(self, request, response): if not hasattr(request, '_cache_update_cache') or not request._cache_update_cache: return False - if self.cache_anonymous_only and has_vary_header(response, 'Cookie'): + # If the session has not been accessed otherwise, we don't want to + # cause it to be accessed here. If it hasn't been accessed, then the + # user's logged-in status has not affected the response anyway. + if self.cache_anonymous_only and self._session_accessed(request): assert hasattr(request, 'user'), "The Django cache middleware with CACHE_MIDDLEWARE_ANONYMOUS_ONLY=True requires authentication middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.auth.middleware.AuthenticationMiddleware' before the CacheMiddleware." if request.user.is_authenticated(): # Don't cache user-variable requests from authenticated users. diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py index ac85f2de747..b31f9a4c55f 100644 --- a/tests/regressiontests/cache/tests.py +++ b/tests/regressiontests/cache/tests.py @@ -1256,6 +1256,28 @@ class CacheMiddlewareTest(unittest.TestCase): self.assertEqual(request.session.accessed, False) + def test_cache_middleware_anonymous_only_with_cache_page(self): + """CACHE_MIDDLEWARE_ANONYMOUS_ONLY should still be effective when used + with the cache_page decorator: the response to a request from an + authenticated user should not be cached.""" + settings.CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True + + request = self.factory.get('/view_anon/') + + class MockAuthenticatedUser(object): + def is_authenticated(self): + return True + + class MockAccessedSession(object): + accessed = True + + request.user = MockAuthenticatedUser() + request.session = MockAccessedSession() + + response = cache_page(hello_world_view)(request, '1') + + self.assertFalse("Cache-Control" in response) + def test_view_decorator(self): # decorate the same view with different cache decorators default_view = cache_page(hello_world_view) diff --git a/tests/regressiontests/cache/urls.py b/tests/regressiontests/cache/urls.py deleted file mode 100644 index b98447bfa3d..00000000000 --- a/tests/regressiontests/cache/urls.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.conf.urls.defaults import patterns - -urlpatterns = patterns('regressiontests.cache.views', - (r'^$', 'home'), -) diff --git a/tests/regressiontests/cache/views.py b/tests/regressiontests/cache/views.py deleted file mode 100644 index 9b72f03f563..00000000000 --- a/tests/regressiontests/cache/views.py +++ /dev/null @@ -1,4 +0,0 @@ -from django.http import HttpResponse - -def home(request): - return HttpResponse('Hello World!')