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中返回字典键的值的values()方法使用
May 22 Python
Python实现数据库编程方法详解
Jun 09 Python
python+selenium实现QQ邮箱自动发送功能
Jan 23 Python
python读取csv和txt数据转换成向量的实例
Feb 12 Python
jupyter notebook 中输出pyecharts图实例
Apr 23 Python
python matplotlib 画dataframe的时间序列图实例
Nov 20 Python
使用python-opencv读取视频,计算视频总帧数及FPS的实现
Dec 10 Python
在keras中获取某一层上的feature map实例
Jan 24 Python
Python RabbitMQ实现简单的进程间通信示例
Jul 02 Python
Python基本数据类型之字符串str
Jul 21 Python
pytorch中的 .view()函数的用法介绍
Mar 17 Python
Python中使用Opencv开发停车位计数器功能
Apr 04 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
ZendFramework框架实现连接两个或多个数据库的方法
2016/12/08 PHP
cssQuery()的下载与使用方法
2007/01/12 Javascript
javascript 事件绑定问题
2011/01/01 Javascript
jQuery 图片切换插件(代码比较少)
2012/05/07 Javascript
调用HttpHanlder的几种返回方式小结
2013/12/20 Javascript
学习使用AngularJS文件上传控件
2016/02/16 Javascript
jquery ztree异步搜索(搜叶子)实践
2016/02/25 Javascript
javascript宿主对象之window.navigator详解
2016/09/07 Javascript
JavaScript之Vue.js【入门基础】
2016/12/06 Javascript
详解本地Node.js服务器作为api服务器的解决办法
2017/02/28 Javascript
整理关于Bootstrap排版的慕课笔记
2017/03/29 Javascript
Angular 4依赖注入学习教程之Injectable装饰器(六)
2017/06/04 Javascript
Node.js中DNS模块学习总结
2018/02/28 Javascript
Webpack path与publicPath的区别详解
2018/05/03 Javascript
详解webpack 热更新优化
2018/09/13 Javascript
vue单页缓存方案分析及实现
2018/09/25 Javascript
VUE.CLI4.0配置多页面入口的实现
2019/11/25 Javascript
React中使用Vditor自定义图片详解
2020/12/25 Javascript
python numpy格式化打印的实例
2018/05/14 Python
Python实现网站表单提交和模板
2019/01/15 Python
python给指定csv表格中的联系人群发邮件(带附件的邮件)
2019/12/31 Python
Python生成随机验证码代码实例解析
2020/06/09 Python
python 装饰器的实际作用有哪些
2020/09/07 Python
python 用Matplotlib作图中有多个Y轴
2020/11/28 Python
Kangol帽子官网:坎戈尔袋鼠
2018/09/26 全球购物
美国快时尚彩妆品牌:Winky Lux(透明花瓣润唇膏)
2018/11/06 全球购物
公司向个人借款协议书范本
2014/10/09 职场文书
缓刑人员思想汇报
2014/10/11 职场文书
疾病证明书
2015/06/19 职场文书
2016春季校长开学典礼致辞
2015/11/26 职场文书
2019年描写人生经典诗句大全
2019/07/08 职场文书
mysql字符串截取函数小结
2021/04/05 MySQL
MySQL数据库如何使用Shell进行连接
2022/04/12 MySQL
Windows server 2012搭建FTP服务器
2022/04/29 Servers
python实现学生信息管理系统(面向对象)
2022/06/05 Python
MySQL数据库表约束讲解
2022/06/21 MySQL