decorator for views that tries getting the page from the cache and populates the cache if the page isn t in the cache yet the cache is keyed by the url and some data from the headers additionally there is the key prefix that is used to distinguish different cache areas in a multisite setup you could use the getcurrentsite domain for example as that is unique across a django project additionally all headers from the response s vary header will be taken into account on caching just like the middleware does ensure argument looks like a request decorator that adds headers to a response so that it will never be cached decorator for views that tries getting the page from the cache and populates the cache if the page isn t in the cache yet the cache is keyed by the url and some data from the headers additionally there is the key prefix that is used to distinguish different cache areas in a multi site setup you could use the get_current_site domain for example as that is unique across a django project additionally all headers from the response s vary header will be taken into account on caching just like the middleware does ensure argument looks like a request decorator that adds headers to a response so that it will never be cached
from functools import wraps

from asgiref.sync import iscoroutinefunction

from django.middleware.cache import CacheMiddleware
from django.utils.cache import add_never_cache_headers, patch_cache_control
from django.utils.decorators import decorator_from_middleware_with_args


def cache_page(timeout, *, cache=None, key_prefix=None):
    
    return decorator_from_middleware_with_args(CacheMiddleware)(
        page_timeout=timeout,
        cache_alias=cache,
        key_prefix=key_prefix,
    )


def _check_request(request, decorator_name):
    
    if not hasattr(request, "META"):
        raise TypeError(
            f"{decorator_name} didn't receive an HttpRequest. If you are "
            "decorating a classmethod, be sure to use @method_decorator."
        )


def cache_control(**kwargs):
    def _cache_controller(viewfunc):
        if iscoroutinefunction(viewfunc):

            async def _view_wrapper(request, *args, **kw):
                _check_request(request, "cache_control")
                response = await viewfunc(request, *args, **kw)
                patch_cache_control(response, **kwargs)
                return response

        else:

            def _view_wrapper(request, *args, **kw):
                _check_request(request, "cache_control")
                response = viewfunc(request, *args, **kw)
                patch_cache_control(response, **kwargs)
                return response

        return wraps(viewfunc)(_view_wrapper)

    return _cache_controller


def never_cache(view_func):
    

    if iscoroutinefunction(view_func):

        async def _view_wrapper(request, *args, **kwargs):
            _check_request(request, "never_cache")
            response = await view_func(request, *args, **kwargs)
            add_never_cache_headers(response)
            return response

    else:

        def _view_wrapper(request, *args, **kwargs):
            _check_request(request, "never_cache")
            response = view_func(request, *args, **kwargs)
            add_never_cache_headers(response)
            return response

    return wraps(view_func)(_view_wrapper)