diff --git a/wagtailcache/cache.py b/wagtailcache/cache.py index 0d92c75..8e9fe8c 100644 --- a/wagtailcache/cache.py +++ b/wagtailcache/cache.py @@ -22,6 +22,7 @@ from django.utils.cache import get_max_age from django.utils.cache import has_vary_header from django.utils.cache import learn_cache_key +from django.utils.cache import patch_cache_control from django.utils.cache import patch_response_headers from django.utils.deprecation import MiddlewareMixin from wagtail import hooks @@ -164,7 +165,7 @@ def _get_cache_key(r: WSGIRequest, c: BaseCache) -> str: def _learn_cache_key( - r: WSGIRequest, s: HttpResponse, t: int, c: BaseCache + r: WSGIRequest, s: HttpResponse, t: Optional[int], c: BaseCache ) -> str: """ Wrapper for Django's learn_cache_key which first strips specific @@ -191,7 +192,6 @@ def __init__(self, get_response=None): def process_request(self, request: WSGIRequest) -> Optional[HttpResponse]: if not wagtailcache_settings.WAGTAIL_CACHE: return None - # Check if request is cacheable # Only cache GET and HEAD requests. # Don't cache requests that are previews. @@ -203,7 +203,6 @@ def process_request(self, request: WSGIRequest) -> Optional[HttpResponse]: and not getattr(request, "is_preview", False) and not (hasattr(request, "user") and request.user.is_authenticated) ) - # Allow the user to override our caching decision. for fn in hooks.get_hooks("is_request_cacheable"): result = fn(request, is_cacheable) @@ -214,16 +213,13 @@ def process_request(self, request: WSGIRequest) -> Optional[HttpResponse]: setattr(request, "_wagtailcache_update", False) setattr(request, "_wagtailcache_skip", True) return None # Don't bother checking the cache. - # Try and get the cached response. try: cache_key = _get_cache_key(request, self._wagcache) - # No cache information available, need to rebuild. if cache_key is None: setattr(request, "_wagtailcache_update", True) return None - # We have a key, get the cached response. response = self._wagcache.get(cache_key) @@ -233,12 +229,10 @@ def process_request(self, request: WSGIRequest) -> Optional[HttpResponse]: setattr(request, "_wagtailcache_error", True) logger.exception("Could not fetch page from cache backend.") return None - # No cache information available, need to rebuild. if response is None: setattr(request, "_wagtailcache_update", True) return None - # Hit. Return cached response. setattr(request, "_wagtailcache_update", False) return response @@ -288,7 +282,6 @@ def process_response( _chop_response_vary(request, response) # We don't need to update the cache, just return. return response - # Check if the response is cacheable # Don't cache private or no-cache responses. # Do cache 200, 301, 302, 304, and 404 codes so that wagtail doesn't @@ -308,29 +301,32 @@ def process_response( and has_vary_header(response, "Cookie") ) ) - # Allow the user to override our caching decision. for fn in hooks.get_hooks("is_response_cacheable"): result = fn(response, is_cacheable) if isinstance(result, bool): is_cacheable = result - # If we are not allowed to cache the response, just return. if not is_cacheable: # Add response header to indicate this was intentionally not cached. _patch_header(response, Status.SKIP) return response - # Potentially remove the ``Vary: Cookie`` header. _chop_response_vary(request, response) # Try to get the timeout from the ``max-age`` section of the # ``Cache-Control`` header before reverting to using the cache's # default. timeout = get_max_age(response) + max_age = timeout if timeout is None: timeout = self._wagcache.default_timeout - patch_response_headers(response, timeout) - if timeout: + max_age = wagtailcache_settings.WAGTAIL_CACHE_MAX_AGE + if max_age is None: + patch_cache_control(response, no_cache=True) + else: + patch_response_headers(response, max_age) + + if timeout != 0: try: cache_key = _learn_cache_key( request, response, timeout, self._wagcache @@ -412,10 +408,9 @@ def _wrapped_view_func( ) -> HttpResponse: # Try to fetch an already cached page from wagtail-cache. response = FetchFromCacheMiddleware().process_request(request) - if response: - return response - # Since we don't have a response at this point, process the request. - response = view_func(request, *args, **kwargs) + if response is None: + # Since we don't have a response at this point, process the request. + response = view_func(request, *args, **kwargs) # Cache the response. response = UpdateCacheMiddleware().process_response(request, response) return response diff --git a/wagtailcache/settings.py b/wagtailcache/settings.py index d56c9a6..380ddba 100644 --- a/wagtailcache/settings.py +++ b/wagtailcache/settings.py @@ -12,6 +12,7 @@ class _DefaultSettings: WAGTAIL_CACHE_BACKEND = "default" WAGTAIL_CACHE_HEADER = "X-Wagtail-Cache" WAGTAIL_CACHE_IGNORE_COOKIES = True + WAGTAIL_CACHE_MAX_AGE = 5 * 60 WAGTAIL_CACHE_IGNORE_QS = [ r"^_bta_.*$", # Bronto r"^_ga$", # Google Analytics diff --git a/wagtailcache/templates/wagtailcache/index.html b/wagtailcache/templates/wagtailcache/index.html index 58aaca0..63f9d80 100644 --- a/wagtailcache/templates/wagtailcache/index.html +++ b/wagtailcache/templates/wagtailcache/index.html @@ -25,7 +25,11 @@

{% trans "Status" %}

{% trans "ENABLED" %}

- {% trans "Cached pages are automatically refreshed every" %} {% cache_timeout %}.
+ {% if cache_timeout == None %} + {% trans "Cached pages do not expire." %}
+ {% else %} + {% trans "Cached pages are automatically refreshed every" %} {{ cache_timeout|seconds_to_readable }}.
+ {% endif %} {% trans "To modify this, change the TIMEOUT value of the cache backend in the project settings." %}

diff --git a/wagtailcache/templatetags/wagtailcache_tags.py b/wagtailcache/templatetags/wagtailcache_tags.py index c1e75b9..48404d1 100644 --- a/wagtailcache/templatetags/wagtailcache_tags.py +++ b/wagtailcache/templatetags/wagtailcache_tags.py @@ -1,7 +1,6 @@ from typing import Optional from django import template -from django.core.cache import caches from django.utils.translation import gettext_lazy as _ from wagtailcache.settings import wagtailcache_settings @@ -10,6 +9,7 @@ register = template.Library() +@register.filter def seconds_to_readable(seconds: int) -> str: """ Converts int seconds to a human readable string. @@ -43,14 +43,3 @@ def get_wagtailcache_setting(value: str) -> Optional[object]: Returns a wagtailcache Django setting, or default. """ return getattr(wagtailcache_settings, value, None) - - -@register.simple_tag -def cache_timeout() -> str: - """ - Returns the wagtailcache timeout in human readable format. - """ - timeout = caches[ - wagtailcache_settings.WAGTAIL_CACHE_BACKEND - ].default_timeout - return seconds_to_readable(timeout) diff --git a/wagtailcache/views.py b/wagtailcache/views.py index 30b5a70..f1b2af6 100644 --- a/wagtailcache/views.py +++ b/wagtailcache/views.py @@ -26,6 +26,9 @@ def index(request): "wagtailcache/index.html", { "keyring": keyring, + "cache_timeout": caches[ + wagtailcache_settings.WAGTAIL_CACHE_BACKEND + ].default_timeout, }, )