首先須要知道前端發給後端的數據格式頭有哪些:前端
以上幾種請求信息中 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