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
原文地址:https://www.cnblogs.com/djfboai/p/10045259.html