Django Rest 框架:Pickle 响应

Dar*_*one 6 django django-rest-framework django-redis

我想做的是构建一个自定义版本,cache_page让我可以更好地控制缓存键,但我什至无法完成响应的基本缓存:

from django.core.cache import cache
from rest_framework import viewsets
from rest_framework.response import Response

from app import models

class BaseViewSet(viewsets.GenericViewSet):
    queryset = models.Items.objects.all()

    def get_queryset(self):
        return models.Items.objects.all()

    def list(self, request, **kwargs):
        response = Response({})
        cache.set('test', response, 10)
        return response
Run Code Online (Sandbox Code Playgroud)

我的相关部分settings.py设置为:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ],
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning'
}
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": f"redis://127.0.0.1:6729/1",
    },
}
Run Code Online (Sandbox Code Playgroud)

当我尝试调用端点时,我得到:

django.template.response.ContentNotRenderedError: The response content must be rendered before it can be pickled.
Run Code Online (Sandbox Code Playgroud)

然后,如果我将该行更改为:

cache.set('test', response.render(), 10)
Run Code Online (Sandbox Code Playgroud)

我得到:

AssertionError: .accepted_renderer not set on Response
Run Code Online (Sandbox Code Playgroud)

(如果我设置渲染器,它会抱怨接受的媒体,然后是上下文,最后会失败TypeError: 'bytes' object is not callable

尽管 API 调用本身在没有缓存的情况下也能正常工作。

cache_page实际上工作正常,所以我知道可以缓存响应,但我不知道我错过了什么。

Cam*_*ima 3

我通过让视图返回 adjango.http.JsonResponse而不是rest_framework.response.Response对象来解决这个问题。问题在于,rest_frameworkResponse与媒体类型无关,据我所知,它依赖于在视图的调用链中进一步设置渲染器和接受的媒体值,在它离开处理程序之后。由于JsonResponse只处理json,所以不必经过这个“内容协商”