class TestView(APIView): def dispatch(self, request, *args, **kwargs): """ 請求到來以後,都要執行dispatch方法,dispatch方法根據請求方式不一樣觸發 get/post/put等方法 注意:APIView中的dispatch方法有好多好多的功能 """ return super().dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): return Response('GET請求,響應內容') def post(self, request, *args, **kwargs): return Response('POST請求,響應內容') def put(self, request, *args, **kwargs): return Response('PUT請求,響應內容')
總體:自建類繼承APIView ,APIView又繼承View類django
入口:CBV/FBV入口都是urls,由此出發restful
分發:urls 裏邊使用as_view方法,通過處理到達dispatch方法,在這作分發ide
終點:執行自定義的認證類post
進入as_view方法 位置···\site-packages\rest_framework\views.py
super(APIView, cls).as_view(**initkwargs)
調用父類View的as_view() 位置 \site-packages\django\views\generic\base.py
最終返回 return self.dispatch(request, *args, **kwargs)this
self是TestView ,沒有dispatch方法,繼續向APIView找
APIView裏邊有 url
···/site-packages/rest_framework/views.py APIView def dispatch()spa
1 def dispatch(self, request, *args, **kwargs): 2 ··· 3 # 在這對request作了一下加工 4 request = self.initialize_request(request, *args, **kwargs) # -->> 對應步驟四、5 -->> 對應步驟四、5 5 ··· 6 # request是豐富後的新request 7 self.initial(request, *args, **kwargs) # -->> 對應步驟六、七、八、9 -->> 對應步驟六、七、八、9 8 ··· 9 # 根據請求反射取屬性,根據method作分發 10 handler = getattr(self, request.method.lower(), 11 self.http_method_not_allowed) 12 response = handler(request, *args, **kwargs)
initialize_request() ···/site-packages/rest_framework/views.py3d
1 def initialize_request(self, request, *args, **kwargs): 2 """ 3 Returns the initial request object. 4 原始request進來,出去是 含request在內的大元祖 5 request基礎上增長了parsers、authenticators、negotiator、parser_context四個屬性 6 四個屬性又對應着四個方法,點擊方法進入查看 7 """ 8 parser_context = self.get_parser_context(request) 9 10 # 把原始的request參數豐富了,利用的是Request類實例化 11 return Request( 12 request, 13 parsers=self.get_parsers(), 14 authenticators=self.get_authenticators(), #獲取用戶認證類 15 negotiator=self.get_content_negotiator(), 16 parser_context=parser_context 17 )
Request() ···\site-packages\rest_framework\request.pyrest
1 class Request(object): 2 def __init__(self, request, parsers=None, authenticators=None, 3 negotiator=None, parser_context=None): 4 ··· 5 self._request = request #原始request的調用方式 6 self.parsers = parsers or () 7 self.authenticators = authenticators or () 8 self.negotiator = negotiator or self._default_negotiator() 9 self.parser_context = parser_context 10 self._data = Empty 11 self._files = Empty 12 self._full_data = Empty 13 self._content_type = Empty 14 self._stream = Empty 15 # 以上是封裝的參數 16 # 此外,還封裝了不少方法,一些加了@property 17 # 先看涉及到的parsers、authenticators、negotiator、parser_context 對應的方法 18 19 def get_parsers(self): 20 """ 21 Instantiates and returns the list of parsers that this view can use. 22 """ 23 return [parser() for parser in self.parser_classes] 24 25 def get_authenticators(self): 26 """ 27 Instantiates and returns the list of authenticators that this view can use. 28 在這把用戶認證類(對象)娶到手了 29 """ 30 return [auth() for auth in self.authentication_classes] 31 32 33 def get_content_negotiator(self): 34 """ 35 Instantiate and return the content negotiation class to use. 36 """ 37 if not getattr(self, '_negotiator', None): 38 self._negotiator = self.content_negotiation_class() 39 return self._negotiator 40 41 def get_parser_context(self, http_request): 42 """ 43 Returns a dict that is passed through to Parser.parse(), 44 as the `parser_context` keyword argument. 45 """ 46 # Note: Additionally `request` and `encoding` will also be added 47 # to the context by the Request object. 48 return { 49 'view': self, 50 'args': getattr(self, 'args', ()), 51 'kwargs': getattr(self, 'kwargs', {}) 52 }
APIView類中:code
def initial(self, request, *args, **kwargs): self.perform_authentication(request) # 調用認證的方法
APIView類中:
def perform_authentication(self, request): # 只有這一句 request.user
認證走到這了,只有一行request.user 說明是user方法裏作的認證
此時request 是新的request 也就是Request() 實例化出來的對象
進去 Request() 找user方法 看看幹了啥
從APIView() 跳到 Request() 裏邊了
@property def user(self): if not hasattr(self, '_user'): with wrap_attributeerrors(): # 執行當前類的_authenticate() 方法 self._authenticate() return self._user
Request() -- _authenticate()方法
def _authenticate(self): # 循環認證全部的類 for authenticator in self.authenticators: try: # authenticators是上邊四、5兩步取出來的 用戶認證類對象 列表 # authenticator對象由用戶認證類實例化而來,用戶認證類確定要支持authenticate()方法 # 這個方法就是給咱們留的鉤子呀,藏得真TM深 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()
整個探索過程當中最重要的是,搞清楚類之間的繼承和引用關係,以及不一樣類包含相同方法時,到底要執行哪一個類。
遇到實在分不清的,能夠打斷點看它到底走的哪。不過打斷點的前提是對程序總體流程有所瞭解