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)