import logging
from rest_framework.views import exception_handler as rest_handler
from rest_framework.response import Response
from django.db import DatabaseError
from redis.exceptions import RedisError
from greentea.response_util import RestResponse
c_fmt = "[%(levelname)s]%(asctime)s %(filename)s.%(funcName)s():line %(lineno)d :
%(message)s"
date_format = "%Y-%m-%d %H:%M:%S %a"
logging.basicConfig(level=logging.INFO, format=c_fmt, datefmt=date_format)
logger = logging.getLogger("drf")
def exception_handler(exc, context):
"""
:param exc: 异常
:param context: 上下文
:return: Response object
"""
response = rest_handler(exc, context)
context_view = context.get("view", None)
context_path = context.get('request').path
context_method = context.get('request').method
context_ip = context.get('request').META.get("REMOTE_ADDR")
if response is None:
logger.error('%s,%s' % (context_view, exc))
response = Response(
{'success': False, 'msg': str(exc).replace('\', ''), "path": context_path, "method": context_method,
'remote_address': context_ip})
return response
if response.status_code == 400:
response = RestResponse(data=response.data, code=response.status_code, status=response.status_code,
msg='400_bad request', success=False)
if response.status_code == 404:
response = RestResponse(data=response.data, code=response.status_code, status=response.status_code,
msg='404_Not Found', success=False)
if response.status_code == 401:
response = RestResponse(data=response.data, code=response.status_code, status=response.status_code,
msg='401_UNAUTHORIZED', success=False)
if response.status_code == 403:
response = RestResponse(data=response.data, code=response.status_code, status=response.status_code,
msg='403_FORBIDDEN ', success=False)
if response.status_code == 405:
response = RestResponse(data=response.data, code=response.status_code, status=response.status_code,
msg='405_METHOD_NOT_ALLOWED', success=False)
if 500 <= response.status_code <= 599:
response = RestResponse(data=response.data, code=response.status_code, status=response.status_code,
msg='INTERNAL_SERVER_ERROR', success=False)
return response
setting.py注册handler,

{
"success": false,
"msg": ""None of [Index(['internal_code', 'project_name', 'version_content', 'version_code',n 'version_size', 'requirement_link', 'person_charge', 'release_time',n 'release_note', 'pass_rate', 'bug_number', 'requirement_change_number',n 'case_numbers'],n dtype='object')] are in the [columns]"",
"path": "/api/batch/import",
"method": "POST",
"remote_address": "127.0.0.1"
}
Response类重写:
from rest_framework.response import Response
from rest_framework.serializers import Serializer
class RestResponse(Response):
def __init__(self, msg=None, success=None, code=None, data=None, status=None,
template_name=None, headers=None,
exception=False, content_type=None):
"""
Alters the init arguments slightly.
For example, drop 'template_name', and instead use 'data'.
Setting 'renderer' and 'media_type' will typically be deferred,
For example being set automatically by the `APIView`.
"""
super(RestResponse, self).__init__(self,None)
if isinstance(data, Serializer):
msg = (
'You passed a Serializer instance as data, but '
'probably meant to pass serialized `.data` or '
'`.error`. representation.'
)
raise AssertionError(msg)
self.code = code
self.msg = msg
self.data = {"data": data or [], "msg": msg or "", "code": code, "success": success}
self.template_name = template_name
self.exception = exception
self.content_type = content_type
if headers:
for name, value in headers.items():
self[name] = value