工作中有需要统一 drf 的json返回 正常响应 和 异常响应的格式
如正常响应统一为
{
'code': 200,
'msg': msg,
'data': data
}
异常响应统一为
{
'code': 0,
'msg': msg
}
解决方案
自定义异常处理类
from rest_framework.response import Response
from rest_framework.views import exception_handler
from rest_framework import status
def custom_exception_handler(exc, context):
res = exception_handler(exc, context)
if res:
# 说明是drf的异常,它处理了
if isinstance(res.data, dict):
detail = res.data.pop('detail', 'error')
else:
detail = res.data[0]
return Response({'code': 0, 'msg': detail}, status=res.status_code)
# 说明是其它异常,它没有处理
return Response({
'code': 0,
'msg': str(exc)
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
自定义json渲染器来统一响应格式
from rest_framework.renderers import JSONRenderer
class CustomRenderer(JSONRenderer):
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', renderer_context["response"].status_code)
else:
msg = 'success'
code = renderer_context["response"].status_code
# 自定义返回数据格式
ret = {
'code': 200,
'msg': msg,
'data': data,
}
if code == 0:
ret.pop('data')
return super().render(ret, accepted_media_type, renderer_context)
else:
return super().render(data, accepted_media_type, renderer_context)
在setting中注册自定义的 异常处理类 和 json 渲染类
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'utils.custom_render.CustomRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
'EXCEPTION_HANDLER': 'utils.custom_exception.custom_exception_handler',
}