<sub id="gqw76"><listing id="gqw76"></listing></sub>
      <sub id="gqw76"><listing id="gqw76"></listing></sub>

    1. <form id="gqw76"><legend id="gqw76"></legend></form>
    2. Django(48)drf請求模塊源碼分析

      前言

      APIView中的dispatch是整個請求生命過程的核心方法,包含了請求模塊,權限驗證,異常模塊和響應模塊,我們先來介紹請求模塊
       

      請求模塊:request對象

       

      源碼入口

      APIView類中dispatch方法中的:request=self.iniialize_request(*args, **kwargs),源碼如下:

      def initialize_request(self, request, *args, **kwargs):
          """
          Returns the initial request object.
          """
          parser_context = self.get_parser_context(request)
      
          return Request(
              request,
              parsers=self.get_parsers(),
              authenticators=self.get_authenticators(),
              negotiator=self.get_content_negotiator(),
              parser_context=parser_context
          )
      

       

      源碼分析

      源碼很簡單,第1句parser_context = self.get_parser_context(request),我們進入方法get_parser_context查看源碼:

      """
      Returns a dict that is passed through to Parser.parse(),
      as the `parser_context` keyword argument.
      """
      # Note: Additionally `request` and `encoding` will also be added
      #       to the context by the Request object.
      return {
          'view': self,
          'args': getattr(self, 'args', ()),
          'kwargs': getattr(self, 'kwargs', {})
      }
      

      上面的代碼的意思是:返回一個解析的字典以便于Parser.parse()去解析,另外還通過Request對象添加了上下文requestencoding
       

      第二句返回了一個Request對象,點擊進入查看

      我們可以分析出,內部對request做了二次封裝,_request是一個HttpRequest對象,并且Request類中還有__getattr__此方法,代碼如下:

      def __getattr__(self, attr):
          """
          If an attribute does not exist on this instance, then we also attempt
          to proxy it to the underlying HttpRequest object.
          """
          try:
              return getattr(self._request, attr)
          except AttributeError:
              return self.__getattribute__(attr)
      

      意思是如果這個實例上不存在一個屬性,那么我們也會嘗試將其代理到底層HttpRequest對象。接下來我們可以通過案例演示
       

      案例演示

      我們創建了TestView視圖,視圖函數中打印了3個request屬性,并且在response上打了一個斷點,接下來通過url訪問視圖,進入斷點如下,

      我們可以清楚的看到:

      • request是drfRequest對象
      • request下有data屬性,query_params屬性,但是沒有GET屬性

      上面還有一個Protected Attributes屬性,里面包含了_request屬性

      我們可以看到_requestWSGIHttpRequest對象,所以它會有GET屬性,所以我們視圖中打印的request.GET實際上和request._request.GET是一樣的,因為request沒有GET屬性,所以它就會訪問_request中的GET屬性,最后我們查看打印結果,如下:

      <QueryDict: {'a': ['1']}>
      <QueryDict: {'a': ['1']}>
      <QueryDict: {'a': ['1']}>
      

       

      同樣的,POST請求也是如此,我們在視圖中添加POST的請求方式,如下:

      def post(self, request, *args, **kwargs):
          print(request.POST)  # 兼容
          print(request._request.POST)  # 二次封裝
          print(request.data)  # 拓展,兼容性最強,3種請求方式都可以
          return Response("drf post ok")
      

      我們都知道提交數據一般有3種方式

      • multipart/form-data
      • application/x-www-form-urlencoded
      • application/json

      首先我們使用multipart/form-data提交請求數據,并請求API

      我們查看pycharm打印結果

      <QueryDict: {'a': ['1']}>
      <QueryDict: {'a': ['1']}>
      <QueryDict: {'a': ['1']}>
      

      可以看到multipart/form-data這種請求方式,都能打印出來
       

      接著我們使用application/x-www-form-urlencoded提交請求數據,并請求API

      <QueryDict: {'a': ['1']}>
      <QueryDict: {'a': ['1']}>
      <QueryDict: {'a': ['1']}>
      

      可以看到application/x-www-form-urlencoded這種請求方式,都能打印出來
       

      最后我們使用application/json提交請求數據,并請求API

      可以看到application/json這種請求方式,只有request.data能打印出來

      <QueryDict: {}>
      <QueryDict: {}>
      {'a': 1}
      

      所以request.data兼容性最強
       

      總結

      1. drfrequest進行了二次封裝,request._request就是原生的WSGIRequest
      2. 原生request的屬性和方法都可以被drfrequest對象直接訪問(兼容)
      3. drf請求的所有url拼接參數均被解析到query_params中,所有的數據包均被解析到data
      4. 其中post請求,request.data的兼容性最強,能兼容前臺傳輸的json格式的數據
      posted @ 2021-06-07 21:14  Silent丿丶黑羽  閱讀(134)  評論(0編輯  收藏  舉報
      最新chease0ldman老人|无码亚洲人妻下载|大香蕉在线看好吊妞视频这里有精品www|亚洲色情综合网

        <sub id="gqw76"><listing id="gqw76"></listing></sub>
        <sub id="gqw76"><listing id="gqw76"></listing></sub>

      1. <form id="gqw76"><legend id="gqw76"></legend></form>