Django Rest 框架:Pickle 响应
Django Rest Framework: Pickle Response
我想做的是构建 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
我的 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",
},
}
当我尝试调用端点时,我得到:
django.template.response.ContentNotRenderedError: The response content must be rendered before it can be pickled.
然后如果我将行更改为:
cache.set('test', response.render(), 10)
我得到:
AssertionError: .accepted_renderer not set on Response
(如果我设置渲染器,它会抱怨已接受的媒体,然后是上下文,最后失败并显示 TypeError: 'bytes' object is not callable
)
尽管 API 调用本身在没有缓存的情况下工作正常。
cache_page
实际上工作正常,所以我知道可以缓存响应,但我不知道我错过了什么。
我通过让视图 return 成为 django.http.JsonResponse
而不是 rest_framework.response.Response
对象解决了这个问题。问题是 rest_framework Response
是媒体类型不可知论者,据我所知依赖于渲染器和接受的媒体值在视图的调用链中进一步设置,在它离开你的之后处理程序。由于 JsonResponse
只处理 json,因此不必经过 "content negotiation".
我想做的是构建 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
我的 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",
},
}
当我尝试调用端点时,我得到:
django.template.response.ContentNotRenderedError: The response content must be rendered before it can be pickled.
然后如果我将行更改为:
cache.set('test', response.render(), 10)
我得到:
AssertionError: .accepted_renderer not set on Response
(如果我设置渲染器,它会抱怨已接受的媒体,然后是上下文,最后失败并显示 TypeError: 'bytes' object is not callable
)
尽管 API 调用本身在没有缓存的情况下工作正常。
cache_page
实际上工作正常,所以我知道可以缓存响应,但我不知道我错过了什么。
我通过让视图 return 成为 django.http.JsonResponse
而不是 rest_framework.response.Response
对象解决了这个问题。问题是 rest_framework Response
是媒体类型不可知论者,据我所知依赖于渲染器和接受的媒体值在视图的调用链中进一步设置,在它离开你的之后处理程序。由于 JsonResponse
只处理 json,因此不必经过 "content negotiation".