Django(48)drf请求模块源码分析
前言
APIView中的dispatch是整个请求生命过程的核心方法,包含了请求模块,权限验证,异常模块和响应模块,我们先来介绍请求模块
请求模块:request对象
源码入口
APIView类中dispatch方法中的:request=self.iniialize_request(*args, **kwargs),源码如下:
def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
"""
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
)
源码分析
源码很简单,第1句parser_context = self.get_parser_context(request),我们进入方法get_parser_context查看源码:
"""
Returns a dict that is passed through to Parser.parse(),
as the `parser_context` keyword argument.
"""
# Note: Additionally `request` and `encoding` will also be added
# to the context by the Request object.
return {
'view': self,
'args': getattr(self, 'args', ()),
'kwargs': getattr(self, 'kwargs', {})
}
上面的代码的意思是:返回一个解析的字典以便于Parser.parse()去解析,另外还通过Request对象添加了上下文request和encoding
第二句返回了一个Request对象,点击进入查看

我们可以分析出,内部对request做了二次封装,_request是一个HttpRequest对象,并且Request类中还有__getattr__此方法,代码如下:
def __getattr__(self, attr):
"""
If an attribute does not exist on this instance, then we also attempt
to proxy it to the underlying HttpRequest object.
"""
try:
return getattr(self._request, attr)
except AttributeError:
return self.__getattribute__(attr)
意思是如果这个实例上不存在一个属性,那么我们也会尝试将其代理到底层HttpRequest对象。接下来我们可以通过案例演示
案例演示

我们创建了TestView视图,视图函数中打印了3个request属性,并且在response上打了一个断点,接下来通过url访问视图,进入断点如下,

我们可以清楚的看到:
- request是
drf的Request对象 - request下有
data属性,query_params属性,但是没有GET属性
上面还有一个Protected Attributes属性,里面包含了_request属性

我们可以看到_request是WSGIHttpRequest对象,所以它会有GET属性,所以我们视图中打印的request.GET实际上和request._request.GET是一样的,因为request没有GET属性,所以它就会访问_request中的GET属性,最后我们查看打印结果,如下:
<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
同样的,POST请求也是如此,我们在视图中添加POST的请求方式,如下:
def post(self, request, *args, **kwargs):
print(request.POST) # 兼容
print(request._request.POST) # 二次封装
print(request.data) # 拓展,兼容性最强,3种请求方式都可以
return Response("drf post ok")
我们都知道提交数据一般有3种方式
- multipart/form-data
- application/x-www-form-urlencoded
- application/json
首先我们使用multipart/form-data提交请求数据,并请求API

我们查看pycharm打印结果
<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
可以看到multipart/form-data这种请求方式,都能打印出来
接着我们使用application/x-www-form-urlencoded提交请求数据,并请求API

<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
可以看到application/x-www-form-urlencoded这种请求方式,都能打印出来
最后我们使用application/json提交请求数据,并请求API

可以看到application/json这种请求方式,只有request.data能打印出来
<QueryDict: {}>
<QueryDict: {}>
{'a': 1}
所以request.data兼容性最强
总结
drf对request进行了二次封装,request._request就是原生的WSGIRequest- 原生
request的属性和方法都可以被drf的request对象直接访问(兼容) drf请求的所有url拼接参数均被解析到query_params中,所有的数据包均被解析到data中- 其中
post请求,request.data的兼容性最强,能兼容前台传输的json格式的数据
Django(48)drf请求模块源码分析的更多相关文章
- Django(51)drf渲染模块源码分析
前言 渲染模块的原理和解析模块是一样,drf默认的渲染有2种方式,一种是json格式,另一种是模板方式. 渲染模块源码入口 入口:APIView类中dispatch方法中的:self.response ...
- Django(49)drf解析模块源码分析
前言 上一篇分析了请求模块的源码,如下: def initialize_request(self, request, *args, **kwargs): """ Retu ...
- Django(50)drf异常模块源码分析
异常模块源码入口 APIView类中dispatch方法中的:response = self.handle_exception(exc) 源码分析 我们点击handle_exception跳转,查看该 ...
- Flask框架 (四)—— 请求上下文源码分析、g对象、第三方插件(flask_session、flask_script、wtforms)、信号
Flask框架 (四)—— 请求上下文源码分析.g对象.第三方插件(flask_session.flask_script.wtforms).信号 目录 请求上下文源码分析.g对象.第三方插件(flas ...
- Spark Scheduler模块源码分析之TaskScheduler和SchedulerBackend
本文是Scheduler模块源码分析的第二篇,第一篇Spark Scheduler模块源码分析之DAGScheduler主要分析了DAGScheduler.本文接下来结合Spark-1.6.0的源码继 ...
- Django的settings文件部分源码分析
Django的settings文件部分源码分析 在编写Django项目的过程中, 其中一个非常强大的功能就是我们可以在settings文件配置许多选项来完成我们预期的功能, 并且这些配置还必须大写, ...
- nginx健康检查模块源码分析
nginx健康检查模块 本文所说的nginx健康检查模块是指nginx_upstream_check_module模块.nginx_upstream_check_module模块是Taobao定制的用 ...
- Spark Scheduler模块源码分析之DAGScheduler
本文主要结合Spark-1.6.0的源码,对Spark中任务调度模块的执行过程进行分析.Spark Application在遇到Action操作时才会真正的提交任务并进行计算.这时Spark会根据Ac ...
- Flask系列10-- Flask请求上下文源码分析
总览 一.基础准备. 1. local类 对于一个类,实例化得到它的对象后,如果开启多个线程对它的属性进行操作,会发现数据时不安全的 import time from threading import ...
随机推荐
- BLE链路层空中包格式
空中包格式 BLE链路层的空中包格式非常简单,它所有的空中包都遵循下图所示的格式: 有上图可见,BLE空中包由4个部分组成,他们分别是: 前导码(Preamble) 访问地址(Access Addre ...
- ARM汇编中的:比较指令--CMN / CMP / TEQ / TST
1. 简介 CMP / CMN : 算术指令 TEQ / TST : 逻辑指令 它们总是会影响CPSR条件标志位. APSR(CPSR)与condition的关系图: 2. CMN -- 比 ...
- 从苏宁电器到卡巴斯基第23篇:难忘的三年硕士时光 I
初次接触逆向工程 不知不觉就来到了2013年的9月份,学校开学了,我开始正式体验研究生的生活了.按道理来说,硕士研究生是需要围绕在导师身边,每天朝九晚五地去实验室做项目的.不过我们老师没有项目,也不要 ...
- LA3027简单带权并查集
题意: 有n个点,一开始大家都是独立的点,然后给出一些关系,a,b表示a是b的父亲节点,距离是abs(a-b)%1000,然后有一些询问,每次询问一个节点a到父亲节点的距离是多少? 思路: ...
- Nmap 扫描器的使用技巧
1.nmap语法 -A 全面扫描/综合扫描 例如:nmap -A 127.0.0.1 扫描指定段 例如:nmap 127.0.0.1-200&nmap 127.0.0.1/24 2.Nmap ...
- TortoiseGit:拉代码密码错误remote: Coding 提示: Authentication failed! 认证失败,请确认您输入了正确的账号密码
问题 在控制面板里找到凭据管理器 修改密码之后拉取密码
- 月薪6K和月薪2W的测试,有什么区别?
之前,我收到了一位朋友的好消息,说自己拿到了接近月薪 20k 的 offer. 说实话,软件测试岗位前期门槛低,但是想要拿到高薪真没那么简单.工作 2-3 年薪资还在原地打转的同学,都大有人在. ...
- 一款好用的数据血缘关系在线工具--SQLFlow
l 数据血缘关系(data lineage) 数据血缘属于数据治理中的一个概念,是在数据溯源的过程中找到相关数据之间的联系,它是一个逻辑概念.数据治理中经常提到血缘分析,血缘分析是保证数据融合的 ...
- repo sync error: .repo/manifests/: contains uncommitted changes
andorid 源码库同步,报错如标题,好几次想放弃,尝试了网上不少办法,无效, 最终从 stackoverflow 得到答案: After issued repo sync, I got a err ...
- nginx日志文件按天记录定时清理循环记录
问题 nginx日志默认记录在一个文件access.log中,时间长了会导致日志文件特别大,甚至磁盘占满. 解决方案 使用以下方法,将access.log文件每天一个,然后清过15天以前的文件. 方法 ...