赞
踩
DRF有自己的异常捕获机制,可以捕获到APIException、Http404、PermissionDenied等异常
处理函数位于rest_framework.views.exception_handler,下面是它的源码
def exception_handler(exc, context): ... if isinstance(exc, Http404): exc = exceptions.NotFound() elif isinstance(exc, PermissionDenied): exc = exceptions.PermissionDenied() if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait if isinstance(exc.detail, (list, dict)): data = exc.detail else: data = {'detail': exc.detail} set_rollback() return Response(data, status=exc.status_code, headers=headers) return None
因为DRF默认的捕获异常的处理函数不能满足项目其他的异常处理,所以我们需要自定义,即重新exception_handler()方法
新建一个py文件,定义一个exception_handler()方法,复制DRF默认的源码,进行修改,先让它默认的处理方式进行处理,处理不了的我们再使用自己的方式处理,若还处理不了,那就返回None
BooksTest/exceptions.py
def exception_handler(exc, context): # 处理得了返回一个响应,处理不了返回None # 1、把异常对象交给DRF的异常处理函数去处理 response = drf_exception_handler(exc, context) if response: # response不为None,说明drf自行处理异常 return response # 2、如果DRF异常处理函数无法处理,我们自行处理,例如处理除数为零的异常、数据库错误的异常等 if isinstance(exc, ZeroDivisionError): return Response({'errmsg': '除数不能为零'}) if isinstance(exc, DatabaseError): return Response({'errmsg': '数据库错误!'}) return None
虽然 我们写了exception_handler(),但是Django不知道,所以我们要指定使用它而不是默认的处理函数
settings.py
REST_FRAMEWORK = {
# ......
# 自定义异常处理函数的导包路径
'EXCEPTION_HANDLER': 'BooksTest.exceptions.exception_handler',
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。