Django Rest Framework之解析器
基本代码结构
urls.py:
from django.conf.urls import url, include
from web.views.s5_parser import TestView urlpatterns = [
url(r'test/', TestView.as_view(), name='test'),
]
views.py:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import JSONParser class TestView(APIView):
# JSONParser:请求头content-type为application/json
# FormParser:请求头content-type为application/x-www-form-urlencoded
# MultiPartParser: 请求头content-type为multipart/form-data
# FileUploadParser:上传文件
parser_classes = [JSONParser, FormParser, MultiPartParser, FileUploadParser, ] def post(self, request, *args, **kwargs):
print(request.content_type) # 获取请求的值,并使用对应的JSONParser进行处理
print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
print(request.POST)
print(request.FILES) return Response('POST请求,响应内容') def put(self, request, *args, **kwargs):
return Response('PUT请求,响应内容')
parser_classes属性变量中的值,是各种解析器对象。前端会向后台发送不同类型的请求,而django后台的drf接口必须通过配置解析器才能获取到相关请求数据。常用的解析器主要是“JSONParser”和“FormParser”这两个解析器。
源码分析
为什么会使用parser_classes属性变量,它有什么用?

同样还是从APIView类的入口方法dispatch入口,在dispatch方法中,调用了initialize_request方法。这个方法在前文中已经说过,是用来封装django原生的request请求的。由上图知道,django原生的request请求数据被封装到了Request对象中,在实例化该对象时,将解析数据的解析器初始化到了parsers属性变量中。

跳转到get_parsers方法中,可以看到,同样也是返回的是列表生成式。

再跳转回APIView类中,可以看到属性变量parser_classes定义的地方。同样也可以通过settings配置文件进行全局配置。如果不需要进行全局配置,那就要在自定义的视图类中对parser_classes属性变量进行重新赋值,即:“parser_classes = [JSONParser, FormParser, MultiPartParser, FileUploadParser,]”。这列表元素都是解析器对象,只要这样配置好,drf就会根据parser_classes中的解析器去解析数据。
为什么从request.data中获取数据?

既然要分析为什么是从data中获取数据,那么分析的入口点当然就是data了。我们知道,django原生的request请求,会被drf通过Request对象封装,那么就跳转到Request类定义中看看这个“data”的实现。在data方法的实现中可以看到前端请求的数据是通过“_load_data_and_files”方法获取的,并且返回值是“_full_data”属性变量。先跳转到“_load_data_and_files”方法中:


在“_load_data_and_files”方法中可知,是通过调用“_parse”方法去获取请求数据的,并且将请求数据保存在“_data”和“_files”属性变量中。除文件相关的数据外的数据都保存在了“_data”中,而“_data”中的数据又都赋值到“_full_data”属性变量中。又由上一张图可知,“data”方法的返回值是“_full_data”,即:data方法获取到的数据就是“_full_data”中的数据。
再往下看,“content_type”属性变量是用来保存请求头的,所以,在基本代码结构中看到,只有设置了某些请求头才会通过“request.POST”来获取请求数据。
下面跳转到“_parse”方法中:



在“_parse”方法中,可以看到将获取到的请求头保存到了“media_type”变量中。然后又通过调用“select_parser(self, self.parsers)”方法,来选择所需要的解析器(参数“self.parsers”就是我们在自定义视图中“parser_classes”的值)。
又通过,parser_classes中解析器对象中的parser方法来解析请求到的数据,即:“parsed = parser.parse(steam, media_type, self.parser_context)”。这里以“JSONParser”对象为例,由上图可知,media_type属性变量中保存的是该解析器所对应的请求头,self.parser_context中,保存的是从前端请求中获取到的请求头。
再来到“JSONParser”类的“parse”方法中可知,再通过返回“json.load”来处理请求数据。返回的请求数据就会保存到“Request”类的“_parse”方法中的parsed变量中。而_parse方法的返回值为元组,第一个元素就是需要的数据。这些数据会在“_load_data_and_files”方法中,赋值给“Request”类的“_data”属性方法,而_data中的数据会赋值给“_full_data”中。因此,“Request”类中“data”方法返回值是“_full_data”,这样,就可以通过“request.data”获取请求数据。
全局配置
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES':[
'rest_framework.parsers.JSONParser'
'rest_framework.parsers.FormParser'
'rest_framework.parsers.MultiPartParser'
]
}
配置加入不同的解析器,就会解析不同类型的请求数据,当然是可以同时配置加入多个解析器的。同样的,配置了全局解析器后,那么,在自定义的视图类中,就可以不用通过“parser_classes”属性变量进行添加解析器的。
Django Rest Framework之解析器的更多相关文章
- Django Rest framework 之 解析器
RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...
- DRF Django REST framework 之 解析器(二)
引入 Django Rest framework帮助我们实现了处理application/json协议请求的数据,如果不使用DRF,直接从 request.body 里面拿到原始的客户端请求的字节数据 ...
- Django REST framework的解析器与渲染器
解析器 解析器的作用 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己可以处理的数据.本质就是对请求体中的数据进行解析. 在了解解析器之前,我们要先知道Accept以及ContentTy ...
- Django REST Framework - 分页 - 渲染器 - 解析器
为什么要使用分页? 我们数据表中可能会有成千上万条数据,当我们访问某张表的所有数据时,我们不太可能需要一次把所有的数据都展示出来,因为数据量很大,对服务端的内存压力比较大还有就是网络传输过程中耗时也会 ...
- rest framework 之解析器
一.示例 1.api/urls.py from django.urls import path, re_path from api.views import UserView, ParserView ...
- Django REST Framework的序列化器是什么?
# 转载请留言联系 用Django开发RESTful风格的API存在着很多重复的步骤.详细可见:https://www.cnblogs.com/chichung/p/9933861.html 过程往往 ...
- django rest framework 自定义验证器
一.基于钩子函数: 官网上的例子: 官方提示:如果字段声明在序列化类上时,就具有参数required=Fasle的作用,当函数名中没有包括字段名时,那么这个验证函数就不起作用 二.基于类的验证器: 使 ...
- Django Rest framework 之 序列化
RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...
- Django Rest framework 之 版本
RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...
随机推荐
- kubernetes中filebeat以sidecar方式和应用一起部署,并且传入环境变量
本文的环境介绍 [root@m-30-1 ~]# kubectl version Client Version: version.Info{Major:"1", Minor:&qu ...
- hdu 1069 Monkey and Banana 【动态规划】
题目 题意:研究人员要测试猴子的IQ,将香蕉挂到一定高度,给猴子一些不同大小的箱子,箱子数量不限,让猩猩通过叠长方体来够到香蕉. 现在给你N种长方体, 要求:位于上面的长方体的长和宽 要小于 下面 ...
- cobub razor 安装及使用
server端安装及配置 apache2 + Mysql5.7 + php7 + redis 参见:http://docs.cobub.com/pages/viewpage.action?pageId ...
- Linux Ubuntu部署web环境及项目tomcat+jdk+mysql
1,下载文件 在官网下载好 tomcat.jdk.mysql的linux压缩包 后缀名为.tar.gz 并通过xftp上传到服务器 或者直接通过linux命令 下在wget文件的下载地址 例如: wg ...
- 788. Rotated Digits
X is a good number if after rotating each digit individually by 180 degrees, we get a valid number t ...
- Eclipse 刚检出的项目 Build path 的时候提示 No action available
问题: 从SVN检出来的项目发现无法进行build path,也不报错,任何类之间也无法关联(Ctrl+右键无法点进去). 原因: .classpath是Eclipse的工程文件,别人没有将工程的信息 ...
- LabVIEW(十五):右键菜单添加创建VI模版
如果在项目研究中使用到的某一个模版文件次数较多,可以单独为某一个模版文件新建右键选项.以文本格式打开注册表,添加的右键内容即为Data后面的内容.Reg内容不可手动修改,可以通过LabVIEW的编程实 ...
- Python基础入门教程(3)
人生苦短,我学Pyhton Python(英语发音:/ˈpaɪθən/), 是一种面向对象.解释型计算机程序设计语言,由Guido van Rossum于1989年底发明,第一个公开发行版发行于199 ...
- HoloLens开发手记 - HoloLens上的应用视图 App views on HoloLens
运行在HoloLens上的应用可能包含2种视图,分别是全息视图和2D视图.应用可以在全息视图和2D视图之间转换,这常被用于访问系统提供的接口,例如虚拟键盘.拥有至少一个全息视图的应用被归类为全息应用. ...
- [每天解决一问题系列 - 0009] File System Redirector
问题描述: 在64位操作系统下,知道Wow64是干什么的,但一直不知道是怎么工作的 相关解释: https://msdn.microsoft.com/en-us/library/windows/des ...