解析模块的使用

解析模块的使用

一、使用

服务器根据设置的请求头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默认支持三种数据的解析,可以全局或局部配置视图类具体支持的解析方式
原文地址:https://www.cnblogs.com/randysun/p/12291387.html