Django drf请求模块源码解析


Posted in Python onJune 08, 2021

DRF 框架,全称为 Django Rest Framework,是 Django 内置模块的扩展,用于创建标准化 RESTful API;它利用 ORM 映射数据库,并自定义序列化数据进行返回,多用于前后端分离项目

项目地址:

https://github.com/encode/django-rest-framework

请求模块: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对象添加了上下文requestencoding

第二句返回了一个Request对象,点击进入查看

Django drf请求模块源码解析

我们可以分析出,内部对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对象。接下来我们可以通过案例演示

案例演示

Django drf请求模块源码解析

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

Django drf请求模块源码解析

我们可以清楚的看到:

  • request是drfRequest对象
  • request下有data属性,query_params属性,但是没有GET属性

上面还有一个Protected Attributes属性,里面包含了_request属性

Django drf请求模块源码解析

我们可以看到_requestWSGIHttpRequest对象,所以它会有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

Django drf请求模块源码解析

我们查看pycharm打印结果

<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>

可以看到multipart/form-data这种请求方式,都能打印出来

接着我们使用application/x-www-form-urlencoded提交请求数据,并请求API

Django drf请求模块源码解析

<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>

可以看到application/x-www-form-urlencoded这种请求方式,都能打印出来

最后我们使用application/json提交请求数据,并请求API

Django drf请求模块源码解析

可以看到application/json这种请求方式,只有request.data能打印出来

<QueryDict: {}>
<QueryDict: {}>
{'a': 1}

所以request.data兼容性最强

总结drfrequest进行了二次封装,request._request就是原生的WSGIRequest原生request的属性和方法都可以被drfrequest对象直接访问(兼容)drf请求的所有url拼接参数均被解析到query_params中,所有的数据包均被解析到data中其中post请求,request.data的兼容性最强,能兼容前台传输的json格式的数据

到此这篇关于Django(48)drf请求模块源码分析 的文章就介绍到这了,更多相关Django drf源码内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python lambda和Python def区别分析
Nov 30 Python
Python中if __name__ == '__main__'作用解析
Jun 29 Python
Python抓取淘宝下拉框关键词的方法
Jul 08 Python
python如何去除字符串中不想要的字符
Jul 05 Python
python指定写入文件时的编码格式方法
Jun 07 Python
Python列表对象实现原理详解
Jul 01 Python
python的debug实用工具 pdb详解
Jul 12 Python
解决pytorch GPU 计算过程中出现内存耗尽的问题
Aug 19 Python
Python定时任务APScheduler原理及实例解析
May 30 Python
Python requests及aiohttp速度对比代码实例
Jul 16 Python
解决使用Pandas 读取超过65536行的Excel文件问题
Nov 10 Python
python基础之类属性和实例属性
Oct 24 Python
Python中OpenCV实现查找轮廓的实例
python字符串的多行输出的实例详解
Jun 08 #Python
Python机器学习之基于Pytorch实现猫狗分类
Python中json.load()和json.loads()有哪些区别
python 爬取哔哩哔哩up主信息和投稿视频
Jun 07 #Python
OpenCV-Python直方图均衡化实现图像去雾
OpenCV-Python实现人脸磨皮算法
You might like
php opendir()列出目录下所有文件的实例代码
2016/10/02 PHP
PHP+Redis链表解决高并发下商品超卖问题(实现原理及步骤)
2020/08/03 PHP
js中的replace方法使用介绍
2013/10/28 Javascript
javascript 动态创建表格
2015/01/08 Javascript
JQuery记住用户名密码实现下次自动登录功能
2015/04/27 Javascript
如何解决谷歌浏览器下jquery无法获取图片的尺寸
2015/09/10 Javascript
Knockout结合Bootstrap创建动态UI实现产品列表管理
2016/09/14 Javascript
Bootstrap 填充Json数据的实例代码
2017/01/11 Javascript
jQuery时间验证和转换为标准格式的时间格式
2017/03/06 Javascript
vue 2.0路由之路由嵌套示例详解
2017/05/08 Javascript
angularjs+bootstrap实现自定义分页的实例代码
2017/06/19 Javascript
使用Vue.js和Flask来构建一个单页的App的示例
2018/03/21 Javascript
从零开始实现Vue简单的Toast插件
2018/12/03 Javascript
Fetch超时设置与终止请求详解
2019/05/18 Javascript
小程序跳转到的H5页面再跳转回跳小程序的方法
2020/03/06 Javascript
python Selenium爬取内容并存储至MySQL数据库的实现代码
2017/03/16 Python
python简单验证码识别的实现方法
2019/05/10 Python
Python3内置模块之json编解码方法小结【推荐】
2020/12/09 Python
解决Django一个表单对应多个按钮的问题
2019/07/18 Python
PyQt 图解Qt Designer工具的使用方法
2019/08/06 Python
Tensorflow 实现将图像与标签数据转化为tfRecord文件
2020/02/17 Python
Python hashlib和hmac模块使用方法解析
2020/12/08 Python
python des,aes,rsa加解密的实现
2021/01/16 Python
详解appium自动化测试工具(monitor、uiautomatorviewer)
2021/01/27 Python
Charlotte Tilbury美国官网:英国美妆品牌
2017/10/13 全球购物
多媒体编辑专业毕业生推荐信
2013/11/05 职场文书
生产经理的自我评价分享
2013/11/07 职场文书
营销专业应届生求职信
2013/11/26 职场文书
应届电子商务毕业自荐书范文
2014/02/11 职场文书
演讲稿祖国在我心中
2014/05/04 职场文书
2014年小学国庆节活动方案
2014/09/16 职场文书
2014年妇委会工作总结
2014/12/10 职场文书
2016党员学习心得体会范文
2016/01/23 职场文书
Oracle 数据仓库ETL技术之多表插入语句的示例详解
2021/04/12 Oracle
如何用vue实现网页截图你知道吗
2021/11/17 Vue.js
《堡垒之夜》联动《刺客信条》 4月7日正式上线
2022/04/06 其他游戏