drf 自定义返回格式


1.自定义异常处理(custom_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

2.自定义正常返回(render_response.py)

点击查看代码
'''
自定义返回处理
'''

# 导入控制返回的JSON格式的类
from rest_framework.renderers import JSONRenderer


class MyRender(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', 0)
                tmp = data.pop('data', '')
                if isinstance(data, list):
                    data = {
                        'total': len(tmp),
                        'data': tmp
                    }
            elif isinstance(data, list):
                msg = 'success'
                code = 0
                data = {
                    'total': len(data),
                    'data': data
                }
            else:
                msg = 'success'
                code = 0

            # 重新构建返回的JSON字典
            for key in data:
                # 判断是否有自定义的异常的字段
                if key == 'message':
                    msg = data[key]
                    data = ''
                    code = 1

            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)


通过以上三步,drf返回的数据格式就会变成以下形式
单个返回:

批量返回

异常返回


优化

通过上边三不,就可以实现有状态码的返回报文。但是状态码就是在自定义返回中写的0,1两种。如果需要其他状态码,就需要用
return Response({'code': 111, 'msg': 'hahah', 'data': qs})
这种形式组报文。对于这种,可以重写Response来优化。
重写Response
点击查看代码
from rest_framework.response import Response
class APIResponse(Response):
    def __init__(self, code=0, msg='success', data=None, status=None,
                 template_name=None, headers=None,
                 exception=False, content_type=None, **kwargs):
        dic = {'code': code, 'msg': msg}
        if data:
            dic['data'] = data
        if kwargs:
            dic.update(kwargs)

        super().__init__(data=dic, status=status,
                         template_name=template_name, headers=headers,
                         exception=exception, content_type=content_type)
用重写的Response类返回数
 qs = list(Camp.objects.filter(status=0).values())
 return APIResponse(qs)
drf