首页 > 解决方案 > ListCreateAPIView:如何缓存序列化的 QuerySet?

问题描述

我有一个具有单一方法的 DRF 类get_queryset()。我想通过在调用之前queryset拦截请求来为序列化添加缓存,但在自定义中间件/身份验证运行之后。这是我所追求的一个简单的例子: get_queryset

class FooList(generics.ListCreateAPIView)
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = FooSerializer

    def intercept_for_caching(self):
        user = self.request.meta_data['user']
        cached_data = cache.get(f'FooStuff:{user.pk}')
        if cached_data:
            return Response(cached_data)
        else:
            new_data = ? # retrieve serialized queryset
            cache.set(f'FooStuff:{user.pk}', new_data)
            return Response(new_data)

    def get_queryset(self):
        user = self.request.meta_data['user']
        return Foo.objects.filter(user=user)

有什么方法可以挂钩吗?

我知道这cache_page是为这个用例设计的(https://www.django-rest-framework.org/api-guide/caching/),但我无法让它与我们的自定义中间件一起工作。

标签: pythondjangodjango-rest-framework

解决方案


源代码有一个功能list

def list(self, request, *args, **kwargs):
    queryset = self.filter_queryset(self.get_queryset())

    page = self.paginate_queryset(queryset)
    if page is not None:
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data)

    serializer = self.get_serializer(queryset, many=True)
    return Response(serializer.data)

我能够通过覆盖来缓存查询集list

def list(self, request, *args, **kwargs):
    user = self.request.user
    cache = caches['redis']
    cache_key = f'my_cache:{user.pk}'
    cached_results = cache.get(cache_key)
    if cached_results:
        return Response(cached_results)
    else:
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        cache.set(cache_key, serializer.data)
        return Response(serializer.data)

推荐阅读