我想重写“dcango REST”框架的Response
类,以便响应返回响应字典包含三个参数message
,status
和data
大家好,亲爱的
我试图改变Response Class
中的DRF
,以传递两个额外的参数(消息,状态)加上由DRF串行化器提供的数据。message
传递类似于Done
、User Created
或etc的消息,status
传递类似于fail
或success
或etc的消息,此消息可用于在前端和后端之间保留特殊代码。
如果不将此参数返回空字符或空结果返回到客户端
例如,在成功模式下:
{
'data': {
'value_one': 'some data',
'value_two': 'some data',
'value_three': [
'value', 'value', 'value'
],
},
}
'message': 'Done',
'status': 'success',
}
在故障模式下:
{
'data': ['any error message raise by serializer',]
'message': 'Create User Failed',
'status': 'failure',
}
我搜索了一下我的问题,找到了这个解决方案:
如果在我的类中继承
DRF Response Class
并覆盖__init__
方法并获取该方法中的消息、数据和状态,并调用具有自身数据结构的父级init,并在该功能中使用此响应类,例如此实现:from rest_framework.response import Response
class Response(Response):
def __init__(self, data=None, message=None, data_status=None, status=None,
template_name=None, headers=None,
exception=False, content_type=None):
data_content = {
'status': data_status,
'data': data,
'message': message,
}
super(Response, self).__init__(
data=data_content,
status=status,
template_name=template_name,
headers=headers,
exception=exception,
content_type=content_type
)
在成功模式下调用:
return Response(data=serializer.data, message='Done', data_status='success', status=200)
在故障模式下调用:
return Response(data=serializer.errors, message='Create User Failed', data_status='failure', status=400)
在所有视图类中使用自己的响应类
我们在这个解决方案中有
problem
:如果我们使用GenericViews Class
必须覆盖我们在view的逻辑中使用的所有http方法并调用自己的类,这是干的!!还有我找到的其他解决办法。在序列化层中,在
def to_representation(self, instance):
类中有抽象方法Serializer
,并在其他类中实现,如ModelSerializer
类继承> cc>,如果在序列化类中重写该方法,并在发送到视图层之前重取数据,则执行如下:from collections import OrderedDict
class OurSerializer(serializer.ModelSerializer):
....
def to_representation(self, instance):
data = super(serializers.ModelSerializer, self).to_representation(instance)
result = OrderedDict()
result['data'] = data
result['message'] = 'Done'
result['status'] = 'sucssed'
return result
这个解决方案解决了上述问题,但我们又有两个问题
一:如果我们使用嵌套序列化器,并且我们在序列化类中重写这个函数,返回的数据如下:
{
'data': {
'value_one': 'some data',
'value_two': 'some data',
'value_three': {
'data': [
'value', 'value', 'value'
],
'message': 'Done',
'status': 'sucssed',
},
}
'message': 'Done',
'status': 'sucssed',
}
和
Serializer
和message
重复,结构不美观和二:我们不能处理异常在这种模式下,只是处理异常,只是这样的中间件类“AA>”,这是不是有用的方式,我们不能处理任何类型的错误发生在视图,并产生舒适的分离
status
和message
。如果这个问题还有其他好的解决办法,请指点我。
谢谢)
最佳答案
为了解决这个问题,最佳实践(drf已经提出)是使用“renderer”类。呈现器操作并返回结构化响应。
Django使用了像Template Renderer和DRF这样的渲染器来支持这个特性并提供了API Renderers。
要做到这一点,可以在包中提供这样的渲染器(例如app_name.renderers.ApiRenderer
):
from rest_framework.renderers import BaseRenderer
from rest_framework.utils import json
class ApiRenderer(BaseRenderer):
def render(self, data, accepted_media_type=None, renderer_context=None):
response_dict = {
'status': 'failure',
'data': {},
'message': '',
}
if data.get('data'):
response_dict['data'] = data.get('data')
if data.get('status'):
response_dict['status'] = data.get('status')
if data.get('message'):
response_dict['message'] = data.get('message')
data = response_dict
return json.dumps(data)
然后在设置文件中:
REST_FRAMEWORK = {
...
'DEFAULT_RENDERER_CLASSES': (
'app_name.renderers.ApiRenderer',
),
...
}
通过此操作,扩展drf通用视图的所有视图都将使用渲染器。如果需要重写设置,可以对泛型视图类使用
renderer_classes
属性,对api视图函数使用@renderer_classes
装饰符。要覆盖的综合渲染器类在
<virtualenv_dir>/lib/python3.6/site-packages/rest_framework/renderers.py
中可用。关于python - 如何在Django Rest Framework(DRF)中覆盖Response类?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53910545/