From ed7c1a56400d64f109f30df3ce697984cdad7c75 Mon Sep 17 00:00:00 2001 From: mengxun Date: Tue, 19 Aug 2025 15:40:37 +0800 Subject: [PATCH] Fixed #36560 -- Prevented UpdateCacheMiddleware from caching responses with Cache-Control 'no-cache' or 'no-store'. --- django/middleware/cache.py | 13 +++++++++++-- tests/cache/tests.py | 25 +++++++++++++++---------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/django/middleware/cache.py b/django/middleware/cache.py index 10fff365af..8c42a52b4a 100644 --- a/django/middleware/cache.py +++ b/django/middleware/cache.py @@ -100,8 +100,17 @@ class UpdateCacheMiddleware(MiddlewareMixin): ): return response - # Don't cache a response with 'Cache-Control: private' - if "private" in response.get("Cache-Control", ()): + # Don't cache responses when the Cache-Control header is set to + # private, no-cache, or no-store. + cache_control = response.get("Cache-Control", ()) + if any( + directive in cache_control + for directive in ( + "private", + "no-cache", + "no-store", + ) + ): return response # Page timeout takes precedence over the "max-age" and the default diff --git a/tests/cache/tests.py b/tests/cache/tests.py index 0b692194de..c4cf0a84e3 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -2731,16 +2731,21 @@ class CacheMiddlewareTest(SimpleTestCase): ) cache.clear() - def test_cached_control_private_not_cached(self): - """Responses with 'Cache-Control: private' are not cached.""" - view_with_private_cache = cache_page(3)( - cache_control(private=True)(hello_world_view) - ) - request = self.factory.get("/view/") - response = view_with_private_cache(request, "1") - self.assertEqual(response.content, b"Hello World 1") - response = view_with_private_cache(request, "2") - self.assertEqual(response.content, b"Hello World 2") + def test_cache_control_not_cached(self): + """ + Responses with 'Cache-Control: private/no-cache/no-store' are + not cached. + """ + for cc in ("private", "no-cache", "no-store"): + with self.subTest(cache_control=cc): + view_with_cache = cache_page(3)( + cache_control(**{cc: True})(hello_world_view) + ) + request = self.factory.get("/view/") + response = view_with_cache(request, "1") + self.assertEqual(response.content, b"Hello World 1") + response = view_with_cache(request, "2") + self.assertEqual(response.content, b"Hello World 2") def test_sensitive_cookie_not_cached(self): """