解析器

news/2024/5/18 23:39:38

源码分析

1 在调用request.data时,才进行解析,由此入手
    @property
    def data(self):
        if not _hasattr(self, '_full_data'):
            self._load_data_and_files()
        return self._full_data
        
2 查看self._load_data_and_files()方法---->self._data, self._files = self._parse()

        def _parse(self):
            #用户请求头里content_type的值
            media_type = self.content_type

            #self.parsers 就是用户配置的parser_classes = [FileUploadParser,FormParser ]
            #self里就有content_type,传入此函数
            parser = self.negotiator.select_parser(self, self.parsers)

3 查看self.negotiator.select_parser(self, self.parsers)
     def select_parser(self, request, parsers):
        #同过media_type和request.content_type比较,来返回解析器,然后调用解析器的解析方法
        #每个解析器都有media_type = 'multipart/form-data'属性
        for parser in parsers:
            if media_type_matches(parser.media_type, request.content_type):
                return parser
        return None
    
4 最终调用parser的解析方法来解析parsed = parser.parse(stream, media_type, self.parser_context)

------------------------------------------------------------
1 Request实例化,parsers=self.get_parsers()
    Request(
                request,
                parsers=self.get_parsers(),
                authenticators=self.get_authenticators(),
                negotiator=self.get_content_negotiator(),
                parser_context=parser_context
            )
2 get_parsers方法,循环实例化出self.parser_classes中类对象
    def get_parsers(self):
        return [parser() for parser in self.parser_classes]            

3 self.parser_classes 先从类本身找,找不到去父类找即APIVIew 中的
    parser_classes = api_settings.DEFAULT_PARSER_CLASSES
4 api_settings是一个对象,对象里找DEFAULT_PARSER_CLASSES属性,找不到,会到getattr方法
        def __getattr__(self, attr):
            if attr not in self.defaults:
                raise AttributeError("Invalid API setting: '%s'" % attr)

            try:
                #调用self.user_settings方法,返回一个字典,字典再取attr属性
                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
 5 user_settings方法 ,通过反射去setting配置文件里找REST_FRAMEWORK属性,找不到,返回空字典
    @property
    def user_settings(self):
        if not hasattr(self, '_user_settings'):
            self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})
        return self._user_settings
View Code

 

作用:传过来的数据,解析成字典
使用:
局部使用:
    from rest_framework.parsers import JSONParser,FormParser
    在视图类中:
    parser_classes = [FormParser,]
全局使用
REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES':[
        'rest_framework.parsers.JSONParser'
        'rest_framework.parsers.FormParser'
        'rest_framework.parsers.MultiPartParser'
    ]

}

            局部使用指定的解析器:
            在视图类中:
            parser_classes = [FormParser,]

 

转载于:https://www.cnblogs.com/pdun/p/11253926.html


http://www.niftyadmin.cn/n/2097856.html

相关文章

了解javascript中的apply和call

apply和call是javascript中很重要的方法,虽然平时编程很少接触到,但是JS框架中到处在使用这2个方法。 这2个方法是在Function.prototype中,也就是说每个JS函数都有这2个方法。 alert(Function.prototype.hasOwnProperty("apply")…

2018.6.14

2018.6.14 引入回跳规则(BackJump Rule): [I1,P∘,I2]∥F↪[I1,ℓ]∥F,(C→l)if{[I1,P∘,I2]⊭FExistsCs.t.:F⇒(C→l)I1⊨Cvar(ℓ)undef.inI1var(ℓ)appearsinF[I_1,P^{\circ},I_2]\lVert F\hookrightarrow [I_1,\ell]\lVert F, (C\to l)~if \begin{cases}[I_1,P^{\circ},I…

进制间的互相转换适用版

好久不用进制转换,都忘了 今天回想一下,记录下自己最适合的方法,就是把要转换的进制先换成二进制,再转成目标进制 先是十进制转二进制: 依次除于2,能整除的记录0,不能整除的记录1 4这就是最后的…

计算机里面没有桌面的选项,解决鼠标右击桌面弹出菜单中没有个性化选项问题...

替代方案:在家庭基础版中我们可以通过以下方法进行相关的设置和更改:请打开 控制面板 ,将 查看方式 设置为 大图标 。鼠标指针方案可以通过点击 鼠标 组件进行设置。账户图片可以通过点击 用户账户 组件后,选择 更改图片 进行设置…

【Kali】kali linux的安装和配置

资源准备制作U盘启动盘准备kali_Linux的分区禁用快速启动安装kali_linux配置wifi网络在这篇Blog中笔者将会讲解如何安装kali_linux,kali可以安装到虚拟机上,但这里笔者强烈建议不要安装到虚拟机上,虚拟机上的kali系统可能会有某些功能不能使用&#xff0…

javascript中的稀疏数组(sparse array)和密集数组

学习underscore.js数组相关API的时候,遇到了sparse array这个东西,以前没有接触过。 这里学习下什么是稀疏数组和密集数组。 什么是密集数组呢?在java和C语言中,数组是一片连续的存储空间,有着固定的长度。加入数组其…

C语言和C++中动态申请内存

在C语言和C的动态内存的使用方法是不同的&#xff0c;在C语言中要使用动态内存要包含一个头文件即 #include<malloc.h> 或者是#include<stdlib.h> 然后用C语言的系统函数 void * malloc(usigned size);来获得动态分配的内存&#xff0c;这个函数参数是需要申请的内…

Linux 文件系统基础——块、i节点

linux文件系统是Linux系统的心脏部分&#xff0c;提供了层次结构的目录和文件。文件系统将磁盘空间划分为每1024个字节一组&#xff0c;称为块(也有用512字节为一块的&#xff0c;如&#xff1a;SCOXENIX&#xff09;。编号从0到整个磁盘的最大块数。 全部块可划分为四个部分&a…