django rest_framework 框架的使用03

rest_framework的 數據解析器

首先須要知道前端發給後端的數據格式頭有哪些:前端

  • media_type = 'application/json'
  • media_type = 'application/x-www-form-urlencoded'
  • media_type = 'multipart/form-data'
  • .......

以上幾種請求信息中 rest_framework中已經內置瞭解析器,分別爲:json

from rest_framework.parsers import 
JSONParser, # 解析第一種 
FormParser, # 解析第二種(常見)
FileUploadParser # 解析文件上傳

# 類中 視圖的 配置


class DemoView(ApiView):
    parser_classes = [JSONParser,FormParser]
    # .... do you wna do 
    
    return .....
# 全局配置
REST_FRAMEWORK = {
    "DEFAULT_PARSER_CLASSES": ["rest_framework.parsers.JSONParser", "rest_framework.parsers.FormParser"],
}

接下來咱們來看看源碼:後端

  • 首先看看請求到來以前,解析器怎樣加載的
def initialize_request(self, request, *args, **kwargs):
        """
        Returns the initial request object.
        """
        parser_context = self.get_parser_context(request)
        # self.get_authenticators() seteings配置的一個列表
        # authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
        return Request(
            request,
            
            """看就是在這裏加載的咱們的解析器"""
            parsers=self.get_parsers(),
            
            
            
            authenticators=self.get_authenticators(),
            negotiator=self.get_content_negotiator(),
            parser_context=parser_context
        )


def get_parsers(self):

    """
    Instantiates and returns the list of parsers that this view can use.
    """
    return [parser() for parser in self.parser_classes]
  • 那又是如何觸發解析的呢?
    沒錯就是咱們要拿數據的時候api

    當咱們 調用 request.data 的時候 這時候觸發執行,接下來咱們看下他的源碼app

Request 類中的 data
  @property
    def data(self):
        if not _hasattr(self, '_full_data'):
            self._load_data_and_files()
        return self._full_data


# 調用 self._load_data_and_files()

    def _load_data_and_files(self):
        """
        Parses the request content into `self.data`.
        """
        
        if not _hasattr(self, '_data'):
            self._data, self._files = self._parse()
            if self._files:
                ........

 def _parse(self):
        """
        Parse the request content, returning a two-tuple of (data, files)

        May raise an `UnsupportedMediaType`, or `ParseError` exception.
        """
        
        
        media_type = self.content_type
        
        ..........
        """
        根據self.content_type 選擇解析器
        
         self.parsers =  
         初始化 request的時候
         parsers=self.get_parsers(),
        
        """
        
        parser = self.negotiator.select_parser(self, self.parsers)
        
        
        """選擇對應的解析器 調用 parse 方法 解析"""
        parsed = parser.parse(stream, media_type, self.parser_context)
        
        
        
### 選擇解析器!!!
def select_parser(self, request, parsers):
        """
        Given a list of parsers and a media type, return the appropriate
        parser to handle the incoming request.
        """
        
        
        for parser in parsers:
            if media_type_matches(parser.media_type, request.content_type):
            """找到解析器 """
                return parser
        return None
相關文章
相關標籤/搜索