rest_framework的源码分析

1、从url入口,re_path('book/(?P<bid>\d+)/', views.Book_Detail_modelserializer_cbv.as_view(),name="book_detail"),

2、首先执行Book_Detail_modelserializer_cbv类的as_view的方法,但是Book_Detail_modelserializer_cbv类没有as_view方法,类本身没有as_view方法,那么该怎么办

3、要去父类中找as_view方法

4、Book_Detail_modelserializer_cbv的父类是什么,父类是APIView,所以,我们要到APIView中查找as_view方法

5、我们很容易在APIView中找到as_view方法,所以这里实际是执行的APIView类的as_view方法


6、这个方法返回return csrf_exempt(view),那么我们在看下view这个是什么


7、在as_view方法中有这样一段代码,view = super(APIView, cls).as_view(**initkwargs),这个是调用父类的as_view方法,那么我们看下APIView类的父类是什么


8、从这里我们可以看到,class APIView(View),APIView的父类是View,那么我们在进View类中查看as_view方法


9、View类中的as_view方法的返回值如下:return view ,那么这里已经很明确了,执行Book_Detail_modelserializer_cbv类的as_view方法,实际是执行的APIView的
as_view方法,执行APIView类中的as_view方法,实际是执行View类中的as_view方法,那么我们还要继续看View类中的view方法到底干了什么


10、View类中的view方法的返回值如下:return self.dispatch(request, *args, **kwargs),那么我们就要继续找dispatch这个方法


12、从哪里找dispatch这个方法呢?不一定一定是View这个类的实例对象调用的dispatch方法,我们需要从源头说起


13、Book_Detail_modelserializer_cbv【类】---父类-->APIView【类】--父类-->View【类】---->view【方法】--->dispatch【方法】

14、首先到Book_Detail_modelserializer_cbv类中查找dispatch方法,当然没有找到,因为这个类是我们自定义的,我们根本就没有写这个方法,那么继续往上找,去APIView类中找dispatch


15、然后到APIView类中查找dispatch【方法】,很幸运,我们找到了dispatch这个方法:def dispatch(self, request, *args, **kwargs):


16、下面我们看下这个dispatch方法到底干了什么,这里就到了我们的认证组件了,需要仔细看一下


17、首先看下self.initial(request, *args, **kwargs),这个方法


18、initial方法中有一个self.perform_authentication(request),这个就是我们的认证组件

19、然后在看下perform_authentication方法,这个就是我们的认证组件

20、这个方法只有一行,返回值为request.user,看到这个,大家可能一脸的懵逼,返回一个request属性?大家不要忘记,如果一个实例方法被property修饰,那么调用这个方法的时候
可以直接使用调用属性的方式调用

21、那么现在重点来了,这个request到底是什么,request.user到底是一个属性呢还是一个方法?


22、ok,继续看源码

23、在dispatch方法中,我们看到有这么一段代码:request = self.initialize_request(request, *args, **kwargs),这里的reqeust参数是源生的request,通过initialize_request对
对源生的request做处理


24、下面就看下initialize_request这个方法做了什么事情

25、看一下initialize_request这个方法,这个方法返回了一个Request的实例对象,那么,这里我们就要看下Request的类是什么东西
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)


26、进入Request这个类,很幸运,这个类中有一个user方法,这个方法被property修饰

@property
def user(self):
"""
Returns the user associated with the current request, as authenticated
by the authentication classes provided to the request.
"""
if not hasattr(self, '_user'):
with wrap_attributeerrors():
self._authenticate()
return self._user

27、这里我们看下_authenticate这个方法做了什么事情


28、进入_authenticate方法,看到如下的代码
def _authenticate(self):
"""
Attempt to authenticate the request using each authentication instance
in turn.
"""
for authenticator in self.authenticators:
try:
user_auth_tuple = authenticator.authenticate(self)
except exceptions.APIException:
self._not_authenticated()
raise

if user_auth_tuple is not None:
self._authenticator = authenticator
self.user, self.auth = user_auth_tuple
return

self._not_authenticated()


29、首先我们需要知道for authenticator in self.authenticators:这个是什么东西


30、在Request类中有这么一个属性,这行代码能看懂吗,如果authenticators为真,则self.authenticators 等于authenticators,如果authenticators为假,则self.authenticators
等于一个空的元组


self.authenticators = authenticators or ()

31、下面的重点就是看下authenticators这个是什么东西

32、初始化Request类的时候传递了一个None:def __init__(self, request, parsers=None, authenticators=None,


33、那么我们在看下实例化Request类的时候是否给authenticators传值

34、在来看下这个段代码,就是这段代码在实例化Request的类,我们明显看到authenticators被赋值了,赋值的值为self.get_authenticators()
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)


35、然后在来看下这个方法干什么了,self.get_authenticators()


35、这个方法又非常的简单,内容如下,循环self.authentication_classes,通过字面意思我们就可以知道,self.authentication_classes这个应该是一个类的集合,auth()
是每个类的实例对象,然后把这些实例对象放在list中返回

def get_authenticators(self):
"""
Instantiates and returns the list of authenticators that this view can use.
"""
return [auth() for auth in self.authentication_classes]



36、那么authentication_classes又是什么呢?点击authentication_classes,我们看到如下的代码,看到这个,我们就该知道,这个属性是默认配置,我们可以自己定义这个属性,
然后个性化使用我们的认证插件

authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES


37、我们可以从我们所以用到的类中找这个属性,都找不到,所以这个属性需要我们自己来配


38、配置的这个类,就是我们的这里需要学习的认证组件



posted on 2019-03-05 16:32  bainianminguo  阅读(65)  评论(0编辑  收藏  举报