2022-12-06 05:23:07 +00:00
|
|
|
from collections.abc import Callable
|
2022-12-05 17:55:30 +00:00
|
|
|
from functools import partial, wraps
|
2022-12-06 05:23:07 +00:00
|
|
|
from typing import ParamSpecArgs, ParamSpecKwargs
|
2022-12-05 17:55:30 +00:00
|
|
|
|
2022-12-06 05:23:07 +00:00
|
|
|
from django.http import HttpRequest
|
2022-12-05 17:55:30 +00:00
|
|
|
from django.views.decorators.cache import cache_page as dj_cache_page
|
|
|
|
|
|
|
|
from core.models import Config
|
|
|
|
|
2022-12-06 05:23:07 +00:00
|
|
|
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 17:55:30 +00:00
|
|
|
|
|
|
|
def cache_page(
|
|
|
|
timeout: int | str = "cache_timeout_page_default",
|
|
|
|
*,
|
|
|
|
key_prefix: str = "",
|
2022-12-06 05:23:07 +00:00
|
|
|
public_only: bool = False,
|
|
|
|
vary_by: VaryByFunc | list[VaryByFunc] | None = None,
|
2022-12-05 17:55:30 +00:00
|
|
|
):
|
|
|
|
"""
|
|
|
|
Decorator for views that caches the page result.
|
|
|
|
timeout can either be the number of seconds or the name of a SystemOptions
|
|
|
|
value.
|
2022-12-06 05:23:07 +00:00
|
|
|
If public_only is True, requests with an identity are not cached.
|
2022-12-05 17:55:30 +00:00
|
|
|
"""
|
2022-12-05 21:48:02 +00:00
|
|
|
_timeout = timeout
|
2022-12-06 05:23:07 +00:00
|
|
|
_prefix = key_prefix
|
|
|
|
if callable(vary_by):
|
|
|
|
vary_by = [vary_by]
|
2022-12-05 17:55:30 +00:00
|
|
|
|
|
|
|
def decorator(function):
|
|
|
|
@wraps(function)
|
|
|
|
def inner(request, *args, **kwargs):
|
2022-12-06 05:23:07 +00:00
|
|
|
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)
|
|
|
|
|
2022-12-05 21:48:02 +00:00
|
|
|
if isinstance(_timeout, str):
|
|
|
|
timeout = getattr(Config.system, _timeout)
|
|
|
|
else:
|
|
|
|
timeout = _timeout
|
2022-12-06 05:23:07 +00:00
|
|
|
|
2022-12-05 21:48:02 +00:00
|
|
|
return dj_cache_page(timeout=timeout, key_prefix=prefix)(function)(
|
2022-12-05 17:55:30 +00:00
|
|
|
request, *args, **kwargs
|
|
|
|
)
|
|
|
|
|
|
|
|
return inner
|
|
|
|
|
|
|
|
return decorator
|
|
|
|
|
|
|
|
|
2022-12-06 05:23:07 +00:00
|
|
|
cache_page_by_ap_json = partial(cache_page, vary_by=[vary_by_ap_json])
|