zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    sqlhelper使用指南
    大三学长带我学习JAVA。作业1. 第1讲.Java.SE入门、JDK的下载与安装、第一个Java程序、Java程序的编译与执行 大三学长带我学习JAVA。作业1.
    pku1201 Intervals
    hdu 1364 king
    pku 3268 Silver Cow Party
    pku 3169 Layout
    hdu 2680 Choose the best route
    hdu 2983
    pku 1716 Integer Intervals
    pku 2387 Til the Cows Come Home
  • 原文地址:https://www.cnblogs.com/benson321/p/9670088.html
Copyright © 2011-2022 走看看