Django Rest Framework -解析器

基本代码结构

urls.py

rom django.conf.urls import url, include
from web.views.s5_parser import TestViewurlpatterns = [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 JSONParserclass 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”这两个解析器。

源码分析

1.为什么使用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中的解析器去解析数据。

 2.为什么从request.data中获取数据?

看到这里,心中有了疑惑,Django Rest Framework框架是在那里触发解析器这个功能的,在上面的源码分析中并未调用任何一个关于解析相关功能的方法,只是做了一个读取配置文件,封装新的request对象的过程,所以是在我们需要读数据的时候才会去触发解析器这个功能,所以我们从request.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”中的数据。

  

现在进一步分析_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”属性变量进行添加解析器的。

 

                             

 

转载于:https://www.cnblogs.com/kxsph/p/10596949.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/449462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

真格量化——菜粕策略

#!/usr/bin/env python # coding:utf-8 from PoboAPI import * import datetime import time import numpy as np from copy import *#开始时间,用于初始化一些参数 def OnStart(context) :context.myacc = None#登录交易账号if context.accounts["回测期货"].Login…

PostgreSQL查看版本信息

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 1.查看客户端版本 psql --version 1 2.查看服务器端版本 2.1 查看详细信息 select version(); 1 2.2 查看版本信息 show server_ve…

U盘版便携式Linux制作, casper-rw 解析

一直都在想,不管用谁的电脑,我都可以得到一个完全一致的工作环境,上面有我喜爱的软件,有我保存的重要资料,甚至浏览器的各种偏好都得一模一样!现在的云计算技术可以部分解决这个问题,但是远远不…

真格量化-50ETF期权波动率策略

#!/usr/bin/env python # coding:utf-8 from PoboAPI import * import datetime import time import numpy as np #日线级别 #开始时间,用于初始化一些参数 def OnStart(context) :print("I\m starting...")#设定一个全局变量品种,本策略交易50ETF期权g.code = Get…

canvas反向裁剪技巧

我们都知道在canvas 可以通过clip来实现剪裁功能,其步骤一般是先设置要裁剪的区域(路径),然后通过ctx.clip()的实现裁剪,裁剪之后,后续的绘制只能在裁剪的区域显示效果,比如如下一段代码&#x…

set 和select 的区别

简单赋值是没有区别的 转载于:https://www.cnblogs.com/bingyizhihun/p/10597908.html

postgres大版本升级

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。进行升级版本之前请一定做好备份!查看当前版本:[postgresnode1 ~]$ psqlpsql (9.4.4)Type "help" for h…

马上有钱:揭密25种成为有钱人的方法(图)

1、做你真正感兴趣的事—你会花很多时间在上面,因此你一定要感兴趣才行,如果不是这样的话,你不愿意把时间花在上面,就得不到成功。 2、自己当老板。为别人打工,你绝不会变成巨富,老板一心一意地缩减开支&a…

无人承运平台系统流程图

转载于:https://www.cnblogs.com/procedureMonkey/p/10598052.html

Neither the JAVA_HOME nor the JRE_HOME environment variable is defined

Centos7.5 启动tomcat报错 报错: Neither the JAVA_HOME nor the JRE_HOME environment variable is defined At least one of these environment variable is needed to run this program原因:没有安装java 解决方法:安装java yum install java -y转载于:https://www.cnblogs…

让自己变成一个上进的人

1.认真设计你的环境2.引入外部监督 求“绑架”3.获取不确定的反馈4.选择一条既细密,又永无止境的职业上升台阶。转载于:https://www.cnblogs.com/Julietma/p/10600241.html

年买笔记本的8个小技巧 最适合自己才最好(组图)

显然,智能手机和平板在一定程度上可以替代传统电脑,让我们可以随时随地上网、使用各种应用。不过,传统电脑也拥有它的不可替代性,比如移动办公、视频编辑、玩游戏,笔记本电脑可能是个更好的选择。 作为一种成熟的电脑…

MySql查询系统时间,SQLServer查询系统时间,Oracle查询系统时间

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 MySQL查询系统时间 第一种方法:select current_date; MySQL> select current_date as Systemtime; 第二…

flask同源策略解决办法及flask-cors只允许特定域名跨域

falsk 同源策略解决办法: 使用 flask-cors 包 并且 在代码里 加响应的一行代码解决。 from flask import Flask, session from flask_cors import CORSapp Flask(__name__) CORS(app, resources{r"/*": {"origins": "*"}}) # 允许…

基本变量和引用变量

基本数据类型作比较,值相等则相等,值不相等则不相等(忽略数据类型) 引用类型作比较,引用地址相等则相等,否则都是不等的。 基本数据类型,和引用数据类型作比较,是比较值是否相等&…

真格量化-持仓量第n档卖方主力跟随策略

#!/usr/bin/env python # coding:utf-8 from PoboAPI import * import datetime import time import numpy as np import pandas as pd #日线级别 #开始时间,用于初始化一些参数 def OnStart(context):print("I\m starting...")#设定一个全局变量品种,本策略交易50E…

赚大钱必备 怎样成为赚钱高手(图)

1、一旦有赚钱的念头就马上一步一个脚印去做,要付诸行动,敢于碰,善于磨,只有这样才能抓住机会。 2、想赚钱,就要立志当商人,而且目标要高,选定十万、二十万,再是一百万、五百万。 …

不定长图片验证码训练

基于LSTM和CTCLoss训练不定长图片验证码 Github项目地址:https://github.com/JansonJo/captcha_ocr.git # codingutf-8 """ 将三通道的图片转为灰度图进行训练 """ import itertools import os import re import random import strin…

[云框架]KONG API Gateway v1.5 -框架说明、快速部署、插件开发

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 当前版本采用KONGv0.12.3 当我们决定对应用进行微服务改造时,应用客户端如何与微服务交互的问题也随之而来,毕竟…

真格量化-主力跟买策略

#!/usr/bin/env python # coding:utf-8 from PoboAPI import * import datetime import time import numpy as np import pandas as pd #日线级别 #开始时间,用于初始化一些参数 def OnStart(context):print("I\m starting...")#设定一个全局变量品种,本策略交易50E…