我想重写“dcango REST”框架的Response类,以便响应返回响应字典包含三个参数messagestatusdata
大家好,亲爱的
我试图改变Response Class中的DRF,以传递两个额外的参数(消息,状态)加上由DRF串行化器提供的数据。message传递类似于DoneUser Created或etc的消息,status传递类似于failsuccess或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',
}

Serializermessage重复,结构不美观
和二:我们不能处理异常在这种模式下,只是处理异常,只是这样的中间件类“AA>”,这是不是有用的方式,我们不能处理任何类型的错误发生在视图,并产生舒适的分离statusmessage
如果这个问题还有其他好的解决办法,请指点我。
谢谢)

最佳答案

为了解决这个问题,最佳实践(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/

10-16 12:39