This repository has been archived on 2023-09-24. You can view files and clone it, but cannot push or open issues or pull requests.
takahe/core/decorators.py

80 lines
2.1 KiB
Python
Raw Permalink Normal View History

from collections.abc import Callable
2022-12-05 18:55:30 +01:00
from functools import partial, wraps
from typing import ParamSpecArgs, ParamSpecKwargs
2022-12-05 18:55:30 +01:00
from django.http import HttpRequest
2022-12-05 18:55:30 +01:00
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"
2022-12-05 18:55:30 +01:00
def cache_page(
timeout: int | str = "cache_timeout_page_default",
*,
key_prefix: str = "",
public_only: bool = False,
vary_by: VaryByFunc | list[VaryByFunc] | None = None,
2022-12-05 18:55:30 +01:00
):
"""
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.
2022-12-05 18:55:30 +01:00
"""
_timeout = timeout
_prefix = key_prefix
if callable(vary_by):
vary_by = [vary_by]
2022-12-05 18:55:30 +01:00
def decorator(function):
@wraps(function)
def inner(request, *args, **kwargs):
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)(
2022-12-05 18:55:30 +01:00
request, *args, **kwargs
)
return inner
return decorator
cache_page_by_ap_json = partial(cache_page, vary_by=[vary_by_ap_json])