为什么 drf-extensions CacheResponseMixin 不缓存?

Why isn't the drf-extensions CacheResponseMixin caching?

我正在使用 Django Rest Framework 和 DRF-Extensions 进行缓存。

我有一个带有自定义 list()retrieve() 方法的视图集。我可以在方法上放置 @cache_response() 装饰器,它成功获取并设置到缓存。但是,如果我尝试使用 CacheResponseMixin 什么也不会发生。

作品:

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)

不起作用:

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)

没有给出错误,我的缓存条目根本没有被创建。

阅读源代码(以及文档),看起来 mixin class 仅在您使用默认列表和检索功能时使用。检查来源:

# -*- 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

如您所见,它定义了自己的列表和检索方法。当你在你的 viewset class 中写你的时,它会完全绕过这些。

因此,答案是当您需要编写自己的列表和检索函数时使用装饰器,或者,如果您可以使用内置于 view/viewset 中的默认列表和检索函数,则使用混合 class.