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实现感知机(PLA)算法
Dec 20 Python
Python实现合并同一个文件夹下所有txt文件的方法示例
Apr 26 Python
pyttsx3实现中文文字转语音的方法
Dec 24 Python
python实现图书借阅系统
Feb 20 Python
Python3.5基础之变量、数据结构、条件和循环语句、break与continue语句实例详解
Apr 26 Python
python 使用socket传输图片视频等文件的实现方式
Aug 07 Python
使用virtualenv创建Python环境及PyQT5环境配置的方法
Sep 10 Python
在win64上使用bypy进行百度网盘文件上传功能
Jan 02 Python
python算的上脚本语言吗
Jun 22 Python
Python2与Python3关于字符串编码处理的差别总结
Sep 07 Python
pycharm永久激活超详细教程
Oct 29 Python
python3处理word文档实例分析
Dec 01 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函数array_flip()在重复数组元素删除中的作用
2013/06/27 PHP
php curl获取网页内容(IPV6下超时)的解决办法
2013/07/16 PHP
PHP入门教程之PHP操作MySQL的方法分析
2016/09/11 PHP
thinkphp3.2.0 setInc方法 源码全面解析
2018/01/29 PHP
二级域名或跨域共享Cookies的实现方法
2008/08/07 Javascript
extjs中grid中嵌入动态combobox的应用
2011/01/01 Javascript
jQuery实现类似淘宝购物车全选状态示例
2013/06/26 Javascript
JQuery获取样式中的background-color颜色值的问题
2013/08/20 Javascript
jquery表单验证插件(jquery.validate.js)的3种使用方式
2015/03/28 Javascript
详细总结Javascript中的焦点管理
2016/09/17 Javascript
从零开始搭建一个react项目开发
2018/02/09 Javascript
基于Node.js实现压缩和解压缩的方法
2018/02/13 Javascript
JS实现前端页面的搜索功能
2018/06/12 Javascript
vue-resource请求实现http登录拦截或者路由拦截的方法
2018/07/11 Javascript
Vue中axios的封装(报错、鉴权、跳转、拦截、提示)
2019/08/20 Javascript
使用VUE实现在table中文字信息超过5个隐藏鼠标移到时弹窗显示全部
2019/09/16 Javascript
微信公众号服务器验证Token步骤图解
2019/12/30 Javascript
vue双击事件2.0事件监听(点击-双击-鼠标事件)和事件修饰符操作
2020/07/27 Javascript
JS实现多功能计算器
2020/10/28 Javascript
用python读写excel的方法
2014/11/18 Python
python下MySQLdb用法实例分析
2015/06/08 Python
浅谈python中的数字类型与处理工具
2017/08/02 Python
Python实现可设置持续运行时间、线程数及时间间隔的多线程异步post请求功能
2018/01/11 Python
python读取目录下最新的文件夹方法
2018/12/24 Python
pandas DataFrame创建方法的方式
2019/08/02 Python
使用Python获取当前工作目录和执行命令的位置
2020/03/09 Python
Python实现删除某列中含有空值的行的示例代码
2020/07/20 Python
HTML5中在title标题标签里设置小图标的方法
2020/06/23 HTML / CSS
购买瑞典当代设计的腕表和太阳眼镜:TRIWA
2016/10/30 全球购物
英国领先的品牌珠宝和配件供应商:Acotis Jewellery
2018/03/07 全球购物
售后求职信范文
2014/03/15 职场文书
个人欠款担保书
2014/05/20 职场文书
2015年幼儿园保育员工作总结
2015/04/23 职场文书
民事申诉状范本
2015/05/20 职场文书
幼儿园班级工作总结2015
2015/05/25 职场文书
2019年第四季度财务部门工作计划
2019/11/02 职场文书