diff options
author | Michael Manfre | 2022-12-06 00:23:07 -0500 |
---|---|---|
committer | GitHub | 2022-12-05 22:23:07 -0700 |
commit | b8460b0acd3e833b9ec302d9fa3fb6ab28032c0e (patch) | |
tree | 780d8d9d818447e591ea326c4f3fd809608ff73a /core | |
parent | b0929214d5c4f6df743256cacfb04337b9319aa4 (diff) | |
download | takahe-b8460b0acd3e833b9ec302d9fa3fb6ab28032c0e.tar.gz takahe-b8460b0acd3e833b9ec302d9fa3fb6ab28032c0e.tar.bz2 takahe-b8460b0acd3e833b9ec302d9fa3fb6ab28032c0e.zip |
Only cache unauthenticated page views (#117)
Diffstat (limited to 'core')
-rw-r--r-- | core/decorators.py | 50 | ||||
-rw-r--r-- | core/views.py | 2 |
2 files changed, 45 insertions, 7 deletions
diff --git a/core/decorators.py b/core/decorators.py index fece564..dc8d4d2 100644 --- a/core/decorators.py +++ b/core/decorators.py @@ -1,34 +1,72 @@ +from collections.abc import Callable from functools import partial, wraps +from typing import ParamSpecArgs, ParamSpecKwargs +from django.http import HttpRequest from django.views.decorators.cache import cache_page as dj_cache_page from core.models import Config +VaryByFunc = Callable[[HttpRequest, ParamSpecArgs, ParamSpecKwargs], str] + + +def vary_by_ap_json(request, *args, **kwargs) -> str: + """ + Return a cache usable string token that is different based upon Accept + header. + """ + if request.ap_json: + return "ap_json" + return "not_ap" + + +def vary_by_identity(request, *args, **kwargs) -> str: + """ + Return a cache usable string token that is different based upon the + request.identity + """ + if request.identity: + return f"ident{request.identity.pk}" + return "identNone" + def cache_page( timeout: int | str = "cache_timeout_page_default", *, - per_identity: bool = False, key_prefix: str = "", + public_only: bool = False, + vary_by: VaryByFunc | list[VaryByFunc] | None = None, ): """ Decorator for views that caches the page result. timeout can either be the number of seconds or the name of a SystemOptions value. + If public_only is True, requests with an identity are not cached. """ _timeout = timeout + _prefix = key_prefix + if callable(vary_by): + vary_by = [vary_by] def decorator(function): @wraps(function) def inner(request, *args, **kwargs): - prefix = key_prefix - if per_identity: - identity_id = request.identity.pk if request.identity else "0" - prefix = f"{key_prefix or ''}:ident{identity_id}" + if public_only: + if request.user.is_authenticated: + return function(request, *args, **kwargs) + + prefix = [_prefix] + + if isinstance(vary_by, list): + prefix.extend([vfunc(request, *args, **kwargs) for vfunc in vary_by]) + + prefix = "".join(prefix) + if isinstance(_timeout, str): timeout = getattr(Config.system, _timeout) else: timeout = _timeout + return dj_cache_page(timeout=timeout, key_prefix=prefix)(function)( request, *args, **kwargs ) @@ -38,4 +76,4 @@ def cache_page( return decorator -per_identity_cache_page = partial(cache_page, per_identity=True) +cache_page_by_ap_json = partial(cache_page, vary_by=[vary_by_ap_json]) diff --git a/core/views.py b/core/views.py index a09d925..2772eb8 100644 --- a/core/views.py +++ b/core/views.py @@ -18,7 +18,7 @@ def homepage(request): return LoggedOutHomepage.as_view()(request) -@method_decorator(cache_page(), name="dispatch") +@method_decorator(cache_page(public_only=True), name="dispatch") class LoggedOutHomepage(TemplateView): template_name = "index.html" |