django rest_framework 框架的使用03

时间:2022-03-14 07:26:03
rest_framework的 数据解析器

首先需要知道前端发给后端的数据格式头有哪些:

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

以上几种请求信息中 rest_framework中已经内置了解析器,分别为:

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]
  • 那又是如何触发解析的呢?

    没错就是我们要拿数据的时候

当我们 调用 request.data 的时候 这时候触发执行,接下来我们看下他的源码

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