在 Django Rest Framework 中缓存序列化程序响应

Posted

技术标签:

【中文标题】在 Django Rest Framework 中缓存序列化程序响应【英文标题】:Caching serializer responses in Django Rest Framework 【发布时间】:2021-11-08 12:03:07 【问题描述】:

我正在使用序列化程序来获取特定资源的相关数据,如下所示:

SessionSerializer.py

def to_representation(self, instance):
  response = super().to_representation(instance)
  response["user"] = UserSerializer(instance.user).data
  if instance.experiment:
      response["experiment"] = ExperimentSerializer(instance.experiment).data
  response["last_event"] = EventSerializer(instance.last_global_event).data

  # fetch and return all session answers tied to this session
  response["session_answers"] = instance.sessionanswer_set.values()
  return response

我还在 SessionViewSet 中使用 DRF 缓存装饰器,这似乎工作正常。但是,当实例有更新和/或任何相关实例(如用户)有更新时,我不能使缓存数据无效。

是否有关于如何在更新时清除缓存数据的标准做法或文档?

【问题讨论】:

【参考方案1】:

我就是这样做的,您可以找到并了解更多信息 - 我仍在学习。 这是我的意见。py

from django.core.cache import cache

class stateViewSet(viewsets.ModelViewSet):
    ---
    ---
    def create(self, request, format=None):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            cache.delete('STATE_CACHE_KEY')
            q = state.objects.prefetch_related("states").all()
            cache.set('STATE_CACHE_KEY', q, 2 * 60)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    def list(self, request):
        queryset = cache.get('STATE_CACHE_KEY')
        if queryset is None:
            queryset = self.get_queryset()
            cache.set('STATE_CACHE_KEY', queryset, 2 * 60)
        serializer = self.get_serializer(queryset, many =True)
        return Response(serializer.data)
    def destroy(self, request, *args, **kwargs):
        try:
            instance = self.get_object()
            self.perform_destroy(instance)
            q = state.objects.prefetch_related("states").all()
            cache.delete('STATE_CACHE_KEY')
            cache.set('STATE_CACHE_KEY', q, 2 * 60)
        except Http404:
            pass
        return Response(status=status.HTTP_204_NO_CONTENT)

【讨论】:

【参考方案2】:

监听数据库记录的变化并根据它们进行更改, 你可以使用 django 信号:

https://docs.djangoproject.com/en/3.2/topics/signals/

【讨论】:

这也会更新嵌套关系吗?就像当一个用户被更新并且 Django 信号更新用户缓存时,它也会更新 Session 缓存? 有一个信号叫m2m_changed。你也可以编写一个处理函数来做你想做的事情。这个link很好地解释了用法。

以上是关于在 Django Rest Framework 中缓存序列化程序响应的主要内容,如果未能解决你的问题,请参考以下文章

django使用rest_framework

Django Rest Framework

Django rest framework 身份和权限验证

Django Rest Framework:非模型服务

django-rest-framework - 在可浏览的 API 中自动生成表单?

在 django-rest-framework 中,是不是可以同时使用 oauth 和 session 身份验证?