<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(49)drf解析模塊源碼分析

      前言

      上一篇分析了請求模塊的源碼,如下:

      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
          )
      

      上述源碼中parsers=self.get_parsers()就是解析模塊源碼的入口
       

      源碼分析

      我們點擊get_parsers進入查看該方法

      def get_parsers(self):
          """
          Instantiates and returns the list of parsers that this view can use.
          """
          return [parser() for parser in self.parser_classes]
      

      該方法實例化并返回此視圖可以使用的解析器列表,我們點擊parser_classes,查看解析器列表

      api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
      
      parser_classes = api_settings.DEFAULT_PARSER_CLASSES
      

      我們會發現解析器列表,是從api_settings中的DEFAULT_PARSER_CLASSES查找的,而api_settings又等于APISettings中的DEFAULTS,我們可以從settings中的DEFAUITS列表的DEFAULT_PARSER_CLASSES,如下:

      DEFAULTS = {
          # Base API policies
          'DEFAULT_RENDERER_CLASSES': [
              'rest_framework.renderers.JSONRenderer',
              'rest_framework.renderers.BrowsableAPIRenderer',
          ],
          'DEFAULT_PARSER_CLASSES': [
              'rest_framework.parsers.JSONParser',
              'rest_framework.parsers.FormParser',
              'rest_framework.parsers.MultiPartParser'
          ],
      }
      

      我們可以看到,drf默認的解析器列表中有3個解析器,這3個解析器中都有media_type屬性,代表支持解析的數據提交類型

      • JSONParser:media_type = 'application/json'
      • FormParser:media_type = 'application/x-www-form-urlencoded'
      • MultiPartParser: media_type = 'multipart/form-data'

      如果我們想在以上3個解析器的基礎上,再加上文件類型的解析器,那么需要全局配置。
       

      全局配置

      我們可以在settings.py文件中設置REST_FRAMEWORK配置,具體設置如下:

      REST_FRAMEWORK = {
          'DEFAULT_PARSER_CLASSES': [
                  'rest_framework.parsers.JSONParser',
                  'rest_framework.parsers.FormParser',
                  'rest_framework.parsers.MultiPartParser',
                  'rest_framework.parsers.FileUploadParser'
              ],
      }
      

      這樣,我們以后所有繼承于APIView的類視圖都可以解析上面配置的4種數據類型,但是如果我們想某個視圖只能解析json格式的數據,那么就需要局部配置
       

      局部配置

      默認全局配置是因為我們寫的視圖繼承自APIView,APIView中配置了類屬性parser_classes,所以我們自己編寫的視圖函數中,也設置個類屬性,并且導入JSONParser解析器

      from rest_framework.parsers import JSONParser
      class TestView(APIView):
          # 局部解析類配置
          parser_classes = [JSONParser]
      
          def post(self, request, *args, **kwargs):
              print(request.data)
              return Response("drf post ok")
      

      接著我們使用application/x-www-form-urlencoded提交數據,會有如下報錯

      {
          "detail": "不支持請求中的媒體類型 “application/x-www-form-urlencoded”。"
      }
      

      然后我們使用multipart/form-data提交數據,也會報錯

      {
          "detail": "不支持請求中的媒體類型 “multipart/form-data; boundary=--------------------------022567055086460827891894”。"
      }
      

      最后我們使用application/json提交數據,響應成功

      "drf post ok"
      

       

      自定義解析器

      如果我們想自定義一個解析器,也很簡單,默認的3個解析器都繼承自BaseParser,我們查看下源碼

      class BaseParser:
          """
          All parsers should extend `BaseParser`, specifying a `media_type`
          attribute, and overriding the `.parse()` method.
          """
          media_type = None
      
          def parse(self, stream, media_type=None, parser_context=None):
              """
              Given a stream to read from, return the parsed representation.
              Should return parsed data, or a `DataAndFiles` object consisting of the
              parsed data and files.
              """
              raise NotImplementedError(".parse() must be overridden.")
      

      如果我們需要自定義解析器,那么就必須繼承自BaseParser,并且設置屬性media_type,還要重寫parse方法,有需求的小伙伴可以自行嘗試,這里就不演示了

      posted @ 2021-06-08 06:06  Silent丿丶黑羽  閱讀(152)  評論(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>