美文网首页pythonPython_web开发
Django rest framework自定义返回数据格式

Django rest framework自定义返回数据格式

作者: Hahn_z | 来源:发表于2020-03-24 10:09 被阅读0次

    drf 默认返回的异常格式是这样的

    {
        "username": [
            "该字段是必填项。"
        ],
        "password": [
            "该字段是必填项。"
        ]
    }
    

    但是在实际工作中、这样的数据不利于前端的渲染
    就拿写IOS的AFNetworking为例、他判断请求成功还是失败不是以http的状态码判断的(当然也可以自己封装)
    一般判断返回的code作为判断条件
    当错误返回的时候直接使用response[@"error"]作为错误的提示信息
    ps:response是数据返回的字典 error是错误信息的key

    一般是这样的格式返回(有错误的时候)

    {
        "msg": "username该字段是必填项。",
        "code": 0,
        "data": ""
    }
    

    正确的时候

    {
        "msg": "success",
        "code": 1,
        "data": {
            "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTU4NjMxMDk5NCwianRpIjoiZTkzZDlhYzZhMWM5NDQ2NTgyN2ZkMzJmNWYzNDVlNjIiLCJ1c2VyX2lkIjoxfQ.Nca8X5AClJxVuDK1-wxJBFZI9WzXt2UL3bytyRckqTU",
            "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTg1NjE5Nzk0LCJqdGkiOiI0NjZkMzk2ZThiMjU0MDQxYTE5OWJjZTc5MjRjNDc2ZiIsInVzZXJfaWQiOjF9.9oaLarHvtT8Zo9dV312Y5fE9HtkTp9Uxrx4WWo_8etg",
            "username": "hahn",
            "user_id": 1
        }
    }
    

    想要弄成这样的效果需要自定义drf异常返回和自定义数据返回格式

    在settings.py中
    EXCEPTION_HANDLER对应的是你文件夹路径

    # drf配置
    REST_FRAMEWORK = {
        # 全局配置异常模块
        'EXCEPTION_HANDLER': 'pine_mountain_bridge.utils.exception.custom_exception_handler',
        # 修改默认返回JSON的renderer的类
        'DEFAULT_RENDERER_CLASSES': (
            'pine_mountain_bridge.utils.rendererresponse.customrenderer',
        ),
    }
    

    设置异常返回
    这里我是在pine_mountain_bridge的utils文件夹里面新建了exception.py文件
    这里可以根据你的需求修改、我这个只是参考

    # 自定义异常处理
    from rest_framework.views import exception_handler
    from rest_framework.views import Response
    from rest_framework import status
    
    
    # 将仅针对由引发的异常生成的响应调用异常处理程序。它不会用于视图直接返回的任何响应
    def custom_exception_handler(exc, context):
        response = exception_handler(exc, context)
        
        # 这个循环是取第一个错误的提示用于渲染
        for index, value in enumerate(response.data):
            if index == 0:
                key = value
                value = response.data[key]
    
                if isinstance(value, str):
                    message = value
                else:
                    message = key + value[0]
    
        if response is None:
            # print(exc)    #错误原因   还可以做更详细的原因,通过判断exc信息类型
            # print(context)  #错误信息
            # print('1234 = %s - %s - %s' % (context['view'], context['request'].method, exc))
            return Response({
                'message': '服务器错误'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
    
        else:
            # print('123 = %s - %s - %s' % (context['view'], context['request'].method, exc))
            return Response({
                'message': message,
            }, status=response.status_code, exception=True)
    
        return response
    
    

    设置自定义返回数据结构
    这里我是在pine_mountain_bridge的utils文件夹里面新建了rendererresponse.py文件
    这里可以根据你的需求修改、我这个只是参考

    '''
    自定义返回处理
    '''
    
    # 导入控制返回的JSON格式的类
    from rest_framework.renderers import JSONRenderer
    
    
    class customrenderer(JSONRenderer):
        # 重构render方法
        def render(self, data, accepted_media_type=None, renderer_context=None):
            if renderer_context:
                if isinstance(data, dict):
                    msg = data.pop('msg', 'success')
                    code = data.pop('code', 1)
                else:
                    msg = 'success'
                    state = 1
    
                # 重新构建返回的JSON字典
                for key in data:
                    # 判断是否有自定义的异常的字段
                    if key == 'message':
                        msg = data[key]
                        data = ''
                        code = 0
    
                ret = {
                    'msg': msg,
                    'code': code,
                    'data': data,
                }
                # 返回JSON数据
                return super().render(ret, accepted_media_type, renderer_context)
            else:
                return super().render(data, accepted_media_type, renderer_context)
    
    

    完成了

    到这一步就可以返回这样的结构了

    PS:可以和serializers里面的error_messages一起使用

    默认提示

    {
        "msg": "name该字段是必填项。",
        "state": 0,
        "data": ""
    }
    

    在自己对于的serializers文件中设置error_messages

        name = serializers.CharField(
            error_messages={
                "blank": "请输入名字",
                "required": "请输入名字",
            },
        )
    

    自定义返回
    如果不想有name这个key请修改自定义异常exception.py的代码

    {
        "msg": "name请输入名字",
        "state": 0,
        "data": ""
    }
    

    相关文章

      网友评论

        本文标题:Django rest framework自定义返回数据格式

        本文链接:https://www.haomeiwen.com/subject/nmwnyhtx.html