DRF之之全局异常、接口文档、jwt介绍和原理、base64编码和解码
文章目录
1、全局异常
1.1、全局异常源码介绍
1、只要三大认证,视图类的方法出了异常,都会执行一个函数:rest_framework.views import exception_handler
查看源码:如下
模块: import rest_framework.settings
模块: from rest_framework.views import APIView
import rest_framework.settings # 从settings中找源码
源码84行左右
# Exception handling
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
'NON_FIELD_ERRORS_KEY': 'non_field_errors',
2、drf只要出了异常,就会执行:‘EXCEPTION_HANDLER’: ‘rest_framework.views.exception_handler’ 这个函数
执行这个’EXCEPTION_HANDLER’: ‘rest_framework.views.exception_handler’
就会执行 rest_framework.views.exception_handler
'''
去继承的APIView中的dispatch方法中的
except Exception as exc:
response = self.handle_exception(exc)
异常代码执行handle_exception方法
def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
self.initial(request, *args, **kwargs)
# Get the appropriate handler method
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs)
# 走这一行执行self.handle_exception(exc)代码然后执行handle_exception方法
except Exception as exc:
response = self.handle_exception(exc)
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
'''
'''
执行handle_exception 方法
时就会执行方法中exception_handler = self.get_exception_handler() 这一行代码
但是这一行代码就是 前面 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler’中的rest_framework.views.exception_handle函数
def handle_exception(self, exc):
"""
Handle any exception that occurs, by returning an appropriate response,
or re-raising the error.
"""
if isinstance(exc, (exceptions.NotAuthenticated,
exceptions.AuthenticationFailed)):
# WWW-Authenticate header for 401 responses, else coerce to 403
auth_header = self.get_authenticate_header(self.request)
if auth_header:
exc.auth_header = auth_header
else:
exc.status_code = status.HTTP_403_FORBIDDEN
# 最终执行这一行代码
exception_handler = self.get_exception_handler()
context = self.get_exception_handler_context()
response = exception_handler(exc, context)
if response is None:
self.raise_uncaught_exception(exc)
response.exception = True
return response
'''
3、drf只要出了异常,就会执行:‘EXCEPTION_HANDLER’: ‘rest_framework.views.exception_handler’ 这个函数
看这个函数 rest_framework.views.exception_handler
4、导入这个执行异常函数的模块
from rest_framework.views import exception_handler
点进去里面就是def exception_handler(exc, context):函数
下面是源代码
'''
def exception_handler(exc, context):
"""
Returns the response that should be used for any given exception.
By default we handle the REST framework `APIException`, and also
Django's built-in `Http404` and `PermissionDenied` exceptions.
Any unhandled exceptions may return `None`, which will cause a 500 error
to be raised.
"""
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
'''
1.2、验证drf出现异常就会执行上面exception_handler函数
场景:只要drf出现异常就会执行上面exception_handler函数
设置drf的异常查看是否执行exception_handler函数
-
设置源代码(验证完成要改回来)
-
要执行的drf代码
# 场景只要drf出现异常就会执行上面exception_handler函数
# 设置drf的异常查看是否执行exception_handler函数
from rest_framework.exceptions import APIException
from app01 import models
class BookView(APIView):
def get(self, request)