• Django 之 restframework 解析器源码分析


    解析器分类:

      1. JSONPaser ----> 解析 JSON-serialized data (解析JSON序列化的数据)

      2.FormParser ---->解析form 表单中 urlencoded格式数据(application/x-ww-form-urlencoded)

      3.MartiPartParser---->解析 form 表单中 form-data 格式数据(Multipart/form-data)

      4.FileUploadParser---> 解析 '*/*',(Parser for file upload data.)

    源码中的解析器

    • 展开源码你会发现,每个解析器下面都会定义一个 解析方法(这是一种面向对象的鸭子类型的体现)。

    • 前端传过的数据以及文件,在后端被使用的时候(request.data,request.FILES)时候解析器才执行解析。所以解析器执行的入口是 request.data or request.FILES

    源码部分:

    # Request-->_parse() 方法
        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
            try:
                # 获取 请求body体中的内容
                stream = self.stream
            except RawPostDataException:
                if not hasattr(self._request, '_post'):
                    raise
                # If request.POST has been accessed in middleware, and a method='POST'
                # request was made with 'multipart/form-data', then the request stream
                # will already have been exhausted.
                if self._supports_form_parsing():
                    return (self._request.POST, self._request.FILES)
                stream = None
    
            if stream is None or media_type is None:
                if media_type and is_form_media_type(media_type):
                    empty_data = QueryDict('', encoding=self._request._encoding)
                else:
                    empty_data = {}
                empty_files = MultiValueDict()
                return (empty_data, empty_files)
    		# 选择 解析器 返回解析器对象
            parser = self.negotiator.select_parser(self, self.parsers)
    		# 如果没有解析器就报错
            if not parser:
                raise exceptions.UnsupportedMediaType(media_type)
    
            try:
                # parser 是已选择的解析器对象(有 JSONparser,Formparser,MultiPartParser,FileUploadParser 是种 ,每个对象里都有一个 parse 方法,用于解析数据或文件。(这里是一种面向对象的鸭子类型的体现))
                # 返回解析完的parsed对象
                parsed = parser.parse(stream, media_type, self.parser_context)
            except Exception:
                # If we get an exception during parsing, fill in empty data and
                # re-raise.  Ensures we don't simply repeat the error when
                # attempting to render the browsable renderer response, or when
                # logging the request or similar.
                self._data = QueryDict('', encoding=self._request._encoding)
                self._files = MultiValueDict()
                self._full_data = self._data
                raise
    
            # Parser classes may return the raw data, or a
            # DataAndFiles object.  Unpack the result as required.
            try:
                # 最终返回 parsed对象的数据和文件
                return (parsed.data, parsed.files)
            except AttributeError:
                empty_files = MultiValueDict()
                return (parsed, empty_files)
    

      

    执行流程(以JSON 格式数据为例)

    """
    -->1.request.data
    -->2.执行request.data 中的 self._load_data_and_files()
    -->3.执行self._load_data_and_files() 中的 self._data, self._files = self._parse()
    -->4. 执行self._parse() 
        -->4.1.执行stream = self.stream-->self._load_stream() 获取请求内容
        -->4.2 执行parser = self.negotiator.select_parser(self, self.parsers)获取解析器
            -->4.2.1 执行 self.negotiator = negotiator or self._default_negotiator()
            --> 如果没有传 就去 配置文件中找api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS()
        -->4.3 执行 parsed = parser.parse(stream, media_type, self.parser_context) 返回通过不同解析器解析出来的被解析对象
        -->4.4 返回  
    """
    View Code
  • 相关阅读:
    fetch函数的使用-常见问题
    React的理解-入门指导
    Navicat for mysql 11.1.20激活
    sqlserver使用job删除过期备份文件
    sqlserver删除重复的数据
    提高code效率
    Wampserver红色橙色解决思路----端口冲突是关键
    java mvc框架系列总结ssh,ssm,servlet
    正则表达式入门案例C#
    SpringBoot开发之《兼容http和https同时访问时443端口被占用》
  • 原文地址:https://www.cnblogs.com/qianzhengkai/p/11144238.html
Copyright © 2020-2023  润新知