zoukankan      html  css  js  c++  java
  • AI-解析器-request.data内部如何按照自定义解析格式-解析数据

    QUESTION:post方法中调用request.data方法时,当在Courseview类中添加parser_classes=[ForParser,],
    就可以将数据解析成parser_classes中的数据格式,并且在request.data中打印。为什么? 答:当打印request.data时走源码时,最终会走到[parser()
    for parser in self.parser_classes] ,
    源码的解析方法很简单,使用json序列化和反序列化即可,关键问题是使用的谁的解析方式?是自己写的、还是默认的、还是全局的? 配置parser_classes有三种方式:自己的类(CourseView)下边配置、在全局settings中配置、在defaults中配置。 执行顺序:如果在自己的类下配置,就优先执行自己类中的parser_classes即可,如果没有就在settings中配置parser_classes即可,
    如果不在settings中配置,那么就使用默认的global_settings中的即可。
    **
    class
    APIView(View): def dispatch(self, request, *args, **kwargs): #由于新的request在dispatch方法中 self.args = args self.kwargs = kwargs request = self.initialize_request(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers # deprecate? ** def initialize_request(self, request, *args, **kwargs): 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 ) ** a.点击self.get_parsers() def get_parsers(self): return [parser() for parser in self.parser_classes] #将parser_classes中的解析方法遍历,实例化即可 **

    class APIView(View):
    
        renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
        parser_classes = api_settings.DEFAULT_PARSER_CLASSES
        authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
    
    
    api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
    class APISettings(object):
    
        def __init__(self, user_settings=None, defaults=None, import_strings=None):
            if user_settings:
                self._user_settings = self.__check_user_settings(user_settings)
            self.defaults = defaults or DEFAULTS
            self.import_strings = import_strings or IMPORT_STRINGS
            self._cached_attrs = set()
    
        @property
        def user_settings(self):
            if not hasattr(self, '_user_settings'):
                self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})
            return self._user_settings
    
        def __getattr__(self, attr):
            if attr not in self.defaults:   #defaults默认为空
                raise AttributeError("Invalid API setting: '%s'" % attr)
    
            try:
                # Check if present in user settings
                val = self.user_settings[attr]    #a.如果在全局的settings中没有配置REST_FRAMEWORK,那么
                            elf.user_settings为空,就走except。settings中配置格式为:
                                REST_FRAMEWORK=[
                                      'DEFAULT_PARSER_CLASSES': (
                                        'rest_framework.parsers.JSONParser',
                                         'rest_framework.parsers.FormParser',
                                         'rest_framework.parsers.MultiPartParser'
                                          ),
                                        ] 
         
    except KeyError: # Fall back to defaults  
            val = self.defaults[attr]     #b.在defaults中找DEFAULT_PARSER_CLASSES,
                                 
    可以找到,因为默认的写了这个
    return val

    b.点击Request类
    class Request(object): @property def data(self): if not _hasattr(self, '_full_data'): self._load_data_and_files() return self._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 ** def _parse(self): media_type = self.content_type try: stream = self.stream except RawPostDataException: if not hasattr(self._request, '_post'): raise if self._supports_form_parsing(): return (self._request.POST, self._request.FILES) stream = None if stream is None or media_type is None: if media_type and is_form_media_type(media_type): empty_data = QueryDict('', encoding=self._request._encoding) else: empty_data = {} empty_files = MultiValueDict() return (empty_data, empty_files) parser = self.negotiator.select_parser(self, self.parsers) ** def select_parser(self, request, parsers): for parser in parsers: if media_type_matches(parser.media_type, request.content_type): return parser return None
  • 相关阅读:
    .NET正则基础之——平衡组
    正则基础之——贪婪与非贪婪模式
    正则应用之——日期正则表达式
    文件指针/句柄(FILE*)、文件描述符(fd)以及 文件路径(filepath)的相互转换(完整版,收集,整理)
    linux c 发送邮件
    select, poll和epoll的区别(转)
    linux c 中文支持
    修改远程桌面连接端口(PortNumber)
    libhdfs编译,安装,配置,使用
    C语言字节对齐详解
  • 原文地址:https://www.cnblogs.com/djfboai/p/10045259.html
Copyright © 2011-2022 走看看