import traceback from rest_framework.renderers import JSONRenderer from rest_framework.views import exception_handler from rest_framework.response import Response from rest_framework import status as drf_status import logging logger = logging.getLogger('log') def custome_exception_hander(exc, context): """ 自定义异常处理 """ res = exception_handler(exc, context) if res: return res else: """ 日志记录 """ logger.error(traceback.format_exc()) return None class FitJSONRenderer(JSONRenderer): """ 自行封装的渲染器 """ def render(self, data, accepted_media_type=None, renderer_context=None): """ 如果使用这个render, 普通的response将会被包装成: {"code":200000,"data":"X","msg":"X"} 这样的结果 使用方法: - 全局 REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ('utils.response.FitJSONRenderer', ), } - 局部 class UserCountView(APIView): renderer_classes = [FitJSONRenderer] :param data: :param accepted_media_type: :param renderer_context: :return: {"code":200,"data":"X","msg":"X"} """ response_body = dict(success=True, code=200000, msg='请求成功', data=None) response = renderer_context.get("response") status_code = response.status_code if isinstance(data, dict) and data.keys() == response_body.keys(): response_body = data else: # 处理drf格式的返回数据 if status_code >= 400: # 如果http响应异常 response_body = dict(success=False, code=400000, msg='请求失败', data=None) response_body['data'] = data # data里是详细异常信息 response_body['code'] = status_code*1000 prefix = "" if isinstance(data, dict): prefix = list(data.keys())[0] data = data[prefix] if isinstance(data, list): data = data[0] if prefix != 'detail': response_body['msg'] = prefix + str(data) # 取一部分放入msg,方便前端alert else: response_body['data'] = data renderer_context.get("response").status_code = 200 # 统一成200响应, 可用body里code区分业务异常 return super(FitJSONRenderer, self).render(response_body, accepted_media_type, renderer_context) class SuccessResponse(Response): def __init__(self, data=None, msg='请求成功', code=200000, status=None, template_name=None, headers=None, exception=False, content_type=None): std_data = dict(success=True, code=code, msg=msg, data=data) super().__init__(std_data, status, template_name, headers, exception, content_type) class FailResponse(Response): def __init__(self, msg='请求失败', data=None, code=400000, status=400, template_name=None, headers=None, exception=False, content_type=None): std_data = dict(success=False, code=code, msg=msg, data=data) super().__init__(std_data, status, template_name, headers, exception, content_type)