I'm using Django Rest Framework and the DRF-Extensions for caching.
I have a viewset with custom list()
and retrieve()
methods. I can put @cache_response()
decorators on the methods and it successfully gets and sets to the cache. However, if I try to use CacheResponseMixin
nothing happens.
Works:
class SeriesViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = SeriesSerializer
def get_queryset(self):
series_type = EntityType.objects.get(name='series')
return Container.objects.filter(type=series_type)
@cache_response()
def list(self, request):
series = self.get_queryset()
serializer = SeriesSerializer(series, many=True)
return Response(serializer.data)
@cache_response()
def retrieve(self, request, pk=None):
name = pk
series = self.get_queryset()
show = series.get(data__title=name)
serializer = SeriesSerializer(show)
return Response(serializer.data)
Does NOT work:
class SeriesViewSet(CacheResponseMixin, viewsets.ReadOnlyModelViewSet):
serializer_class = SeriesSerializer
def get_queryset(self):
series_type = EntityType.objects.get(name='series')
return Container.objects.filter(type=series_type)
def list(self, request):
series = self.get_queryset()
serializer = SeriesSerializer(series, many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
name = pk
series = self.get_queryset()
show = series.get(data__title=name)
serializer = SeriesSerializer(show)
return Response(serializer.data)
No errors are given, my cache entry simply doesn't get created.
Reading the source (as well as the docs), it looks like the mixin class is ONLY for use when you use the default list and retrieve functions. Check the source:
# -*- coding: utf-8 -*-
from rest_framework_extensions.cache.decorators import cache_response
from rest_framework_extensions.settings import extensions_api_settings
class BaseCacheResponseMixin(object):
# todo: test me. Create generic test like
# test_cache_reponse(view_instance, method, should_rebuild_after_method_evaluation)
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 ListCacheResponseMixin(BaseCacheResponseMixin):
@cache_response(key_func='list_cache_key_func')
def list(self, request, *args, **kwargs):
return super(ListCacheResponseMixin, self).list(request, *args, **kwargs)
class RetrieveCacheResponseMixin(BaseCacheResponseMixin):
@cache_response(key_func='object_cache_key_func')
def retrieve(self, request, *args, **kwargs):
return super(RetrieveCacheResponseMixin, self).retrieve(request, *args, **kwargs)
class CacheResponseMixin(RetrieveCacheResponseMixin,
ListCacheResponseMixin):
pass
As you can see, it defines its own list and retrieve methods. When you write yours in your viewset class, it bypasses these ones completely.
So, the answer is to use the decorators when you need to write your own list and retrieve functions, or, if you can use the default list and retrieve functions built into the view/viewset, then use the mixin class.