ListCreateAPIView: Как я могу кэшировать сериализованный QuerySet? - PullRequest
0 голосов
/ 07 января 2020

У меня есть класс 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/), но я не смог заставить его работать с нашим специальным промежуточным ПО.

1 Ответ

0 голосов
/ 08 января 2020

Исходный код имеет функцию 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)
...