• DRF-解析器组件源码解析


    解析器组件源码解析

    解析器组件源码解析
    1 执行request.data  开始找重装的request中的data方法
    2     在dispatch找到重装的request
        def dispatch(self, request, *args, **kwargs):
            request = self.initialize_request(request, *args, **kwargs)
    ***这里开始找data
    3 在initialize_request中找到实例request的类Request()
            def initialize_request(self, request, *args, **kwargs):
            """
            Returns the initial request object.
            """
            parser_context = self.get_parser_context(request)
    
            return Request(
                request,
                parsers=self.get_parsers(),
                authenticators=self.get_authenticators(),
                negotiator=self.get_content_negotiator(),
                parser_context=parser_context
            )
        得到类对象Request(),注意parsers=self.get_parsers()后面会回来找
    4 Request()中找到data方法
    5 在data方法中--关注返回值
        @property
        def data(self):
            if not _hasattr(self, '_full_data'):
                self._load_data_and_files()
            return self._full_data
        由于返回值默认:self._full_data = Empty
        所以self._load_data_and_files()应该对_full_data进行复制了
    6 从_load_data_and_files()找到_full_data
            def _load_data_and_files(self):
    
                if not _hasattr(self, '_data'):
                    self._data, self._files = self._parse()
                    if self._files:
                        self._full_data = self._data.copy()
                        self._full_data.update(self._files)
                    else:
                        self._full_data = self._data
        这里我们把self._parse()的结果分别复制给了self._data, self._files,且都放在了_full_data中,接下来观察self._parse()都给了什么值
    7 _parse()
        def _parse():
            parser = self.negotiator.select_parser(self, self.parsers)
            parsed = parser.parse(stream, media_type, self.parser_context)
            empty_files = MultiValueDict()
            return (parsed, empty_files)
        parsed通过parser获取,而传入的参数中的self.parsers,就是我们初始化Request()中传入的参数parsers=self.get_parsers()
    
    // *****这里开始开始和parser_classes我们的设置解析数据类型设置相关了    
    8 我们回到步骤3找到parsers=self.get_parsers()
    9 在get_parsers()中
        return [parser() for parser in self.parser_classes]
        得到从self.parser_classes中循环的列表
    // *****选择从调用的视图类中获取parser_classes,没有从APIView中获取parser_classes
    10 在APIView中获取到parser_classes
        parser_classes = api_settings.DEFAULT_PARSER_CLASSES
    11 从api_settings查找DEFAULT_PARSER_CLASSES方法或属性
        api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
        @property
        def user_settings(self):
            if not hasattr(self, '_user_settings'):
                self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})
            return self._user_settings
        class APISettings():
            def __init__(defaults=None):
                self.defaults = defaults or DEFAULTS 
                # 这里将DEFAULTS字典放在实例对象中,
            def __getattr__(self, attr):
                if attr not in self.defaults:
                    raise AttributeError("Invalid API setting: '%s'" % attr)
    
                try:
                    # Check if present in user settings
                    val = self.user_settings[attr]
                except KeyError:
                    # Fall back to defaults
                    val = self.defaults[attr]
    
                # Coerce import strings into classes
                if attr in self.import_strings:
                    val = perform_import(val, attr)
    
                # Cache the result
                self._cached_attrs.add(attr)
                setattr(self, attr, val)
                return val
        self.defaults = defaults or DEFAULTS --》这里将DEFAULTS字典放在实例对象中,我们发现DEFAULT_PARSER_CLASSES
        就在字典中
        由于没有DEFAULT_PARSER_CLASSES方法,我们执行__getattr__方法
            1***** val = self.user_settings[attr]优先从配置中找有没有配置的路由解析方法,如果没配置
            2***** val = self.defaults[attr]从实例化对象的内存空间中找方法
            3 val = perform_import(val, attr)将'rest_framework.parsers.JSONParser'转化成JSONParser

     解析器顺序

      当前访问视图类下------------》全局settings---------》默认default

    使用

    # 设置全局解析方式
    REST_FRAMEWORK={
    'DEFAULT_PARSER_CLASSES': (
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser'
        ),
    }
    # 当前访问视图类下设置解析方式
    from rest_framework.parsers import JSONParser
    from rest_framework.views import APIView
    
    class LoginView(APIView):
        parser_classes = [JSONParser]
        def get(self,request):
            print('get')
            return render(request,'login.html')
        def post(self,request):
            print('body',request.body)
            print(request.data)
            print('data',request.data)
            # print('POST', request.POST)
            return HttpResponse('OK')
    # 默认使用的解析方式
    class APIView(View):
        parser_classes = api_settings.DEFAULT_PARSER_CLASSES
  • 相关阅读:
    npm ERR! code ELIFECYCLE
    typescript react echarts map geojson
    react ts could not find a declaration file for module
    SQL SERVER 查询存储过程执行时间
    分析云优化方案
    U8 单据弃审失败 解决办法
    RCP的熔断,降级与限流(笔记五)
    RPC的优雅关闭(笔记四)
    RCP的请求路由(笔记三)
    RCP的负载均衡(笔记二)
  • 原文地址:https://www.cnblogs.com/benson321/p/9670088.html
Copyright © 2020-2023  润新知