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之数据类型总结
Sep 24 Python
Python3通过Luhn算法快速验证信用卡卡号的方法
May 14 Python
快速解决安装python没有scripts文件夹的问题
Apr 03 Python
在PyCharm环境中使用Jupyter Notebook的两种方法总结
May 24 Python
对python 命令的-u参数详解
Dec 03 Python
解决python打不开文件(文件不存在)的问题
Feb 18 Python
pandas中DataFrame修改index、columns名的方法示例
Aug 02 Python
python多线程扫描端口(线程池)
Sep 04 Python
如何安装2019Pycharm最新版本(详细教程)
Sep 26 Python
python统计字符的个数代码实例
Feb 07 Python
Python数据分析之pandas函数详解
Apr 21 Python
Python 如何实现文件自动去重
Jun 02 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开发过程中常用函数收藏
2009/12/14 PHP
url decode problem 解决方法
2011/12/26 PHP
功能强大的PHP图片处理类(水印、透明度、旋转)
2015/10/21 PHP
Zend Framework入门教程之Zend_Mail用法示例
2016/12/08 PHP
php获取目录中所有文件名及判断文件与目录的简单方法
2017/03/04 PHP
js 数值项目的格式化函数代码
2010/05/14 Javascript
javascript变量作用域使用中常见错误总结
2013/03/26 Javascript
JS 去前后空格大全(IE9亲测)
2013/07/15 Javascript
jQuery提示效果代码分享
2014/11/20 Javascript
node.js中的path.sep方法使用说明
2014/12/08 Javascript
图文详解JavaScript的原型对象及原型链
2016/08/02 Javascript
JavaScript实现窗口抖动效果
2016/10/19 Javascript
vue2滚动条加载更多数据实现代码
2017/01/10 Javascript
NodeJS模块与ES6模块系统语法及注意点详解
2019/01/04 NodeJs
Vuex新手的理解与使用详解
2019/05/31 Javascript
Jquery+AJAX实现无刷新上传并重命名文件操作示例【PHP后台接收】
2020/05/29 jQuery
python实现人人网登录示例分享
2014/01/19 Python
python 列表删除所有指定元素的方法
2018/04/19 Python
python中yaml配置文件模块的使用详解
2018/04/27 Python
Python零基础入门学习之输入与输出
2019/04/03 Python
python实现网站用户名密码自动登录功能
2019/08/09 Python
python Tensor和Array对比分析
2020/01/08 Python
Linux系统下升级pip的完整步骤
2021/01/31 Python
美国家用电器和电子产品商店:Abt
2016/09/06 全球购物
世界上最大的街头服饰网站:Karmaloop
2017/02/04 全球购物
教师个人自我鉴定
2014/02/08 职场文书
城市轨道交通工程职业生涯规划书范文
2014/09/16 职场文书
常务副县长“四风”个人对照检查材料思想汇报
2014/10/02 职场文书
2014幼儿园教师个人工作总结
2014/11/08 职场文书
家庭财产分割协议范文
2014/11/24 职场文书
党的群众路线教育实践活动先进个人材料
2014/12/24 职场文书
2015年宣传部工作总结范文
2015/03/31 职场文书
2015年计生工作总结范文
2015/04/24 职场文书
严以修身专题学习研讨会发言材料
2015/11/09 职场文书
redis 查看所有的key方式
2021/05/07 Redis
anaconda python3.8安装后降级
2021/06/11 Python