tl;dr; If you use the django.views.decorators.cache.cache_control
decorator, consider this one instead to change the max_age
depending on the request.
I had/have a Django view function that looks something like this:
@cache_control(public=True, max_age=60 * 60)
def home(request, oc=None, page=1):
...
But, that number 60 * 60
I really needed it to be different depending on the request parameters. For example, that oc=None
, if that's not None
I know the page's Cache-Control
header can and should be different.
So I wrote this decorator:
from django.utils.cache import patch_cache_control
def variable_cache_control(**kwargs):
"""Same as django.views.decorators.cache.cache_control except this one will
allow the `max_age` parameter be a callable.
"""
def _cache_controller(viewfunc):
@functools.wraps(viewfunc)
def _cache_controlled(request, *args, **kw):
response = viewfunc(request, *args, **kw)
copied = kwargs
if kwargs.get("max_age") and callable(kwargs["max_age"]):
max_age = kwargs["max_age"](request, *args, **kw)
# Can't re-use, have to create a shallow clone.
copied = dict(kwargs, max_age=max_age)
patch_cache_control(response, **copied)
return response
return _cache_controlled
return _cache_controller
Now, I can do this instead:
def _best_max_age(req, oc=None, **kwargs):
max_age = 60 * 60
if oc:
max_age *= 10
return max_age
@variable_cache_control(public=True, max_age=_best_max_age)
def home(request, oc=None, page=1):
...
I hope it inspires.
Comments