• django rest_framework 框架的使用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
        
    
    
  • 相关阅读:
    DockerAPI版本不匹配的问题
    Linux文件系统
    队列

    多维数组
    字符串
    线性表
    ARM编辑、编译工具
    南京IT公司
    数据结构:用单链表实现的队列(2)
  • 原文地址:https://www.cnblogs.com/zjcode/p/9420842.html
Copyright © 2020-2023  润新知