83 lines
3.3 KiB
Python
83 lines
3.3 KiB
Python
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) |