Python之drf源码分析与全局捕获异常
一、认证源码分析
views.py内认证类使用,与文件自定义认证类
# authentication.py
from rest_framework.authentication import BaseAuthentication
# 继承认证基类BaseAuthentication
class bookAuthentication(BaseAuthentication):
# 重写authenticate方法
def authenticate(self,request):
token = request.GET.get('token')
user_token = UserToken.objects.filter(token=token).first()
if user_token:
# 带的token是有效的
# user_token.user当前登录用户
return user_token.user, token
else:
raise AuthenticationFailed('token不合法或没有迭代token')
# views.py
from .serializers import Bookserializers
from .models import Book
from rest_framework.generics import ListCreateAPIView
from .authentication import bookAuthentication
class BookListCreateAPIView(ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = Bookserializers
authentication_classes = [bookAuthentication,]
源码分析
#1 入口---》APIView的dispatch---》self.initial(request, *args, **kwargs)————》认证类的代码self.perform_authentication(request)
# 2 self.perform_authentication(request)
def perform_authentication(self, request):
request.user # 新的request对象的user方法
# 2 Request类的user方法
@property
def user(self):
if not hasattr(self, '_user'):
with wrap_attributeerrors():
self._authenticate() # 核心就是这句话,是Request的
return self._user
# 3 Request类的_authenticate(self)方法
def _authenticate(self):
for authenticator in self.authenticators: #self.authenticators是个列表,列表中放了一个个认证类的对象
try:
# self是request,所以我们的认证类的authenticate,有两个参数,self给了第二个参数
user_auth_tuple = authenticator.authenticate(self) # 执行认证类的authenticate方法
except exceptions.APIException:
self._not_authenticated()
raise
if user_auth_tuple is not None:
self._authenticator = authenticator
self.user, self.auth = user_auth_tuple #解压赋值,后续的requtst对象就有user属性了
return
self._not_authenticated(