For a project I’m doing I’m looking at adding a conditional header to bypass cache when an X-No-Cache is present. In my case this allows external system to flush cache when certain conditions are met.
I’ve modified code from Django Rest Framework Extension to allow for such behaviour. There might be a better way to do it, but at the moment the flow of the code is clear to me. It also needs drf-extensions
as it’s just an additional mixin that offloads the code to cache_response
decorator.
from rest_framework_extensions.cache.decorators import cache_response
from rest_framework_extensions.settings import extensions_api_settings
class BaseCacheResponseMixin(object):
object_cache_key_func = extensions_api_settings.DEFAULT_OBJECT_CACHE_KEY_FUNC
list_cache_key_func = extensions_api_settings.DEFAULT_LIST_CACHE_KEY_FUNC
class ConditionalListCacheResponseMixin(BaseCacheResponseMixin):
@cache_response(key_func="list_cache_key_func")
def _cached_list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)
def list(self, request, *args, **kwargs):
if request.META.get("HTTP_X_NO_CACHE") == "1":
return super().list(request, *args, **kwargs)
else:
return self._cached_list(request, *args, **kwargs)
class ConditionalRetrieveCacheResponseMixin(BaseCacheResponseMixin):
@cache_response(key_func="object_cache_key_func")
def _cached_retrieve(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)
def retrieve(self, request, *args, **kwargs):
if request.META.get("HTTP_X_NO_CACHE") == "1":
return super().retrieve(request, *args, **kwargs)
else:
return self._cached_retrieve(request, *args, **kwargs)
class ConditionalCacheResponseMixin(
ConditionalRetrieveCacheResponseMixin, ConditionalListCacheResponseMixin
):
pass