zoukankan      html  css  js  c++  java
  • 解析模块的使用

    解析模块的使用

    一、使用

    服务器根据设置的请求头content-type接收客户端对应的数据信息

    # JSONParser: 只接收json数据
    # FormParser: 只接收urlencoded
    # MultiPartParser:只接收form-data
    from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
    
    # 1.局部配置
    # 解析模块的局部配置
    #局部配置禁用就是配置空list[]
    parser_classes = [JSONParser, MultiPartParser, FormParser]
    
    # 2.全局配置
    # drf的配置,在drf中settings.py查看如何配置
    REST_FRAMEWORK = {   
        # 解析模块的全局配置
        'DEFAULT_PARSER_CLASSES': [
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser'
        ]
    }
    
    

    img

    二、源码分析

    # 1.对数据进行二次解析
    def dispatch(self, request, *args, **kwargs):
        """
            `.dispatch()` is pretty much the same as Django's regular dispatch,
            but with extra hooks for startup, finalize, and exception handling.
            """
        self.args = args
        self.kwargs = kwargs
        # 对原生request进行了二次封装,查看解析
        request = self.initialize_request(request, *args, **kwargs)
        ...
        
    # 2 获取解析数据
    def initialize_request(self, request, *args, **kwargs):
        """
            Returns the initial request object.
            """
        # 准备要解析的字典
        parser_context = self.get_parser_context(request)
    
        return Request(
            # 初始wigs中request
            request, 
            # 解析模块在封装原生request是,将数据一并解析
            parsers=self.get_parsers(), 
            authenticators=self.get_authenticators(),
            negotiator=self.get_content_negotiator(),
            parser_context=parser_context # 解析的内容
        )
        
    # 2.1 返回要解析内容字典
    def get_parser_context(self, http_request):
        """
            Returns a dict that is passed through to Parser.parse(),
            as the `parser_context` keyword argument.
            """
        # Note: Additionally `request` and `encoding` will also be added
        #       to the context by the Request object.
        return {
            'view': self,
            'args': getattr(self, 'args', ()),
            'kwargs': getattr(self, 'kwargs', {})
        }
    
    # 3 获取要解析的对象
    def get_parsers(self):
        """
         Instantiates and returns the list of parsers that this view can use.
         """
        return [parser() for parser in self.parser_classes]
    
    class BaseParser:  
        media_type = None
        def parse(self, stream, media_type=None, parser_context=None):      
            raise NotImplementedError(".parse() must be overridden.")
    

    总结:

    1. 根据流程,再次进入drf的dispatch方法,该方法对响应数据进行了二次封装同时也对数据进行了二次解析,然后,进入 request = self.initialize_request(request, *args, **kwargs)方法
    2. 在 self.initialize_request方法中通过self.get_parser_context(request)方法,获取要解析的数据,get_parser_context(self, http_request):方法返回解析的数据字典返回
    3. 在Request类中调用get_parsers(self)方法获取解析的对象,解析的随想先从创建的视图类中(BookAPIView(APIView)(局部配置))找,然后在从自己的项目文件中找(项目中 settings.py,全局配置), 最后从drf默认配置文件中(默认配置),实现数据的解析
    4. 只有在后台设置了解析的数据,才会给前台正确的响应否则报错
    5. 核心:请求的数据包格式会有三种(json、urlencoded、form-data),drf默认支持三种数据的解析,可以全局或局部配置视图类具体支持的解析方式
  • 相关阅读:
    java通过ST4使用模板字符串
    使用 docker创建redis实例并且连接
    Docker 认证成功后还是无法push构建好的镜像
    记录一次在openwrt中折腾docker
    全局模式、PAC模式、直连模式的区别
    Vue Router中调用this.$router.push() 时,location使用path无法传入params
    liunx之系统
    liunx之通配符&正则表达式
    liunx之基础
    liunx之find命令
  • 原文地址:https://www.cnblogs.com/randysun/p/12291387.html
Copyright © 2011-2022 走看看