1. 程式人生 > >python-django rest framework框架之dispatch方法源碼分析

python-django rest framework框架之dispatch方法源碼分析

pytho fault quest 變量 miss imp ons esp cati

1.Django的 CBV 中在請求到來之後,都要執行dispatch方法,dispatch方法根據請求方式不同觸發 get/post/put等方法

class APIView(View):
    def dispatch(self, request, *args, **kwargs):#1.1 把wsgi的request進行封裝
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request     #此時的self.request 是rest_framework的Request對象,它裏面比wsgi的request多了一些東西
try: #1.2 進行 初始化 :版本,認證,權限,訪問頻率 self.initial(request, *args, **kwargs)
#1.3 反射執行get等方法 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) except Exception as exc: response = self.handle_exception(exc) #1.4 把返回的response 再進行封裝 self.response = self.finalize_response(request, response, *args, **kwargs)
#1.5 返回 return self.response

第1.1步:

from rest_framework.request import Request

class APIView(View):
    def initialize_request(self, request, *args, **kwargs):
       #返回了一個rest_framework的Request對象
        return Request(
            request,
       #1.1.1 parsers
=self.get_parsers(),
       #1.1.2 authenticators
=self.get_authenticators(),
       #1.1.3 negotiator
=self.get_content_negotiator(), )

第1.1.1步:

pass

第1.1.2步:

class APIView(View):
    def get_authenticators(self):
     #self.authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES 是從配置文件中取數據,從變量名不難看出有可能是很多類的列表
return [auth() for auth in self.authentication_classes]
     #self.authenticators = 一個多個對象的列表

第1.2步:

class APIView(View):
    def initial(self, request, *args, **kwargs):
     #版本相關
     version, scheme = self.determine_version(request, *args, **kwargs)
#1.2.1認證相關 self.perform_authentication(request) #1.2.2權限相關 self.check_permissions(request) #1.2.3訪問頻率相關 self.check_throttles(request)

第1.2.1步:

class APIView(View):
    def perform_authentication(self, request):
     #1.2.1.1
        request.user

第1.2.1.1步:

class Request(object):    
    @property
    def user(self):       #此時的self 是 rest_framework的request對象
        if not hasattr(self, _user):
            with wrap_attributeerrors():
          #1.2.1.1.1 self._authenticate()
return self._user

1.2.1.1.1步:

class Request(object):    
    def _authenticate(self):
        #此時的self 是 rest_framework的request對象
for authenticator in self.authenticators: #self.authenticators = 一個多個對象的列表 try:
          #執行每個對象的authenticate方法 user_auth_tuple
= authenticator.authenticate(self)   #從變量的名不難看出 返回了一個元組 except exceptions.APIException: self._not_authenticated() raise if user_auth_tuple is not None: self._authenticator = authenticator
          #賦值, request.user和request.auth 並返回 self.user, self.auth
= user_auth_tuple return self._not_authenticated()

第1.3步反射執行get等方法

最後、我們可以自定義一個簡單的用戶認證

class MyAuth(object):
    def authenticate(self,request):
        return "1111","222"
    
class Host(APIView):
    authentication_classes=[MyAuth]
    def get(self,request):
        print(request.user)    #1111
        print(request.auth)   #222
        return HttpResponse("666")

python-django rest framework框架之dispatch方法源碼分析