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 相关文章推荐
centos 安装python3.6环境并配置虚拟环境的详细教程
Feb 22 Python
pandas条件组合筛选和按范围筛选的示例代码
Aug 26 Python
python 解决Fatal error in launcher:错误问题
May 21 Python
python语言中有算法吗
Jun 16 Python
Keras - GPU ID 和显存占用设定步骤
Jun 22 Python
Pandas中DataFrame基本函数整理(小结)
Jul 20 Python
Python 绘制可视化折线图
Jul 22 Python
一篇文章带你搞定Ubuntu中打开Pycharm总是卡顿崩溃
Nov 02 Python
Django自带用户认证系统使用方法解析
Nov 12 Python
pycharm如何设置官方中文(如何汉化)
Dec 29 Python
Django中如何用xlwt生成表格的方法步骤
Jan 31 Python
baselines示例程序train_cartpole.py的ImportError
May 20 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
64位windows系统下安装Memcache缓存
2015/12/06 PHP
PHP对象克隆clone用法示例
2016/09/28 PHP
简单谈谈PHP面向对象之标识对象
2017/06/27 PHP
js之onload事件的一点使用心得
2013/08/14 Javascript
jquery ztree实现下拉树形框使用到了json数据
2014/05/14 Javascript
javascript if条件判断方法小结
2014/05/17 Javascript
JavaScript运动减速效果实例分析
2015/08/04 Javascript
jquery实现美观的导航菜单鼠标提示特效代码
2015/09/06 Javascript
Jquery easyui 实现动态树
2015/11/17 Javascript
jQuery实现定位滚动条位置
2016/08/05 Javascript
jQuery实现的3D版图片轮播示例【滑动轮播】
2019/01/18 jQuery
Vue中通过Vue.extend动态创建实例的方法
2019/08/13 Javascript
Vue打包后访问静态资源路径问题
2019/11/08 Javascript
JavaScript实现简单计算器功能
2019/12/19 Javascript
微信小程序连接服务器展示MQTT数据信息的实现
2020/07/14 Javascript
wxpython实现图书管理系统
2018/03/12 Python
用Python写脚本,实现完全备份和增量备份的示例
2018/04/29 Python
Python的log日志功能及设置方法
2019/07/11 Python
python GUI库图形界面开发之PyQt5多线程中信号与槽的详细使用方法与实例
2020/03/08 Python
python爬虫开发之selenium模块详细使用方法与实例全解
2020/03/09 Python
python实现udp聊天窗口
2020/03/31 Python
Python requests模块cookie实例解析
2020/04/14 Python
Python flask框架实现浏览器点击自定义跳转页面
2020/06/04 Python
Django如何批量创建Model
2020/09/01 Python
牵手50台湾:专为黄金岁月的单身人士而设的交友网站
2021/02/18 全球购物
室内设计自我鉴定
2013/10/15 职场文书
英语专业毕业生求职简历的自我评价
2013/10/24 职场文书
医学专业毕业生推荐信
2013/11/14 职场文书
装潢设计专业推荐信模板
2013/11/26 职场文书
25岁生日感言
2014/01/13 职场文书
网上签名寄语活动留言
2014/01/18 职场文书
物业管理工作方案
2014/05/10 职场文书
亲子阅读的活动方案
2014/08/15 职场文书
技术股份合作协议书
2014/10/05 职场文书
学生保证书
2015/01/16 职场文书
浅谈JS和Nodejs中的事件驱动
2021/05/05 NodeJs