我正在创建一个API,需要所有JSON响应的自定义结构。
{
code: 200,
payload: [
{...},
{...},
{...}
]
}
payload
包含查询返回的所有项目。
我已经创建了一个扩展Renderer
的自定义JSONRenderer
,但为了访问响应代码,我需要访问render_context
。
class VendorRenderer(JSONRenderer):
def render(self, data, accepted_media_type=None, render_context=None):
response = render_context['response']
data = {
'code': response.status_code,
'payload': data
}
return super(VendorRenderer, self).render(data, accepted_media_type, render_context)
这是进行此类包装的正确位置还是应该在ViewSet等其他地方进行,或者通过扩展Response对象?
答案 0 :(得分:5)
这是包装响应的正确位置,因为在中间件中执行错误检查后会呈现响应。
在视图中执行此操作可能会导致意外结果,例如,code
参数无法正确捕获序列化错误,并将其包装在自定义序列化程序中将无法访问响应对象。此外,您可能希望在响应中包含身份验证或限制错误。
请注意,发生的任何分页也将包含在您的payload
参数中:
{
"code":200,
"payload": {
"count": 20,
"next": 2,
"previous": 0,
"results": [
...
]
}
}
对此的一个解决方案是使用HTTP标头实现分页。
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
class StandardResultsSetHeaderPagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 1000
def get_paginated_response(self, data):
headers = {
'X-Count': self.page.paginator.count,
'X-Next': self.get_next_link(),
'X-Previous': self.get_previous_link()
}
return Response(data, headers=headers)