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代码(逐级优化)
May 25 Python
python处理圆角图片、圆形图片的例子
Apr 25 Python
java中两个byte数组实现合并的示例
May 09 Python
实例分析python3实现并发访问水平切分表
Sep 29 Python
Pandas统计重复的列里面的值方法
Jan 30 Python
把JSON数据格式转换为Python的类对象方法详解(两种方法)
Jun 04 Python
ubuntu 18.04搭建python环境(pycharm+anaconda)
Jun 14 Python
Python 操作 ElasticSearch的完整代码
Aug 04 Python
使用Python实现正态分布、正态分布采样
Nov 20 Python
Python 实现判断图片格式并转换,将转换的图像存到生成的文件夹中
Jan 13 Python
pycharm部署、配置anaconda环境的教程
Mar 24 Python
Python字符串split及rsplit方法原理详解
Jun 29 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
十大感人催泪爱情动漫 第一名至今不忍在看第二遍
2020/03/04 日漫
PHP简单获取视频预览图的方法
2015/03/12 PHP
php生成静态html页面的方法(2种方法)
2015/09/14 PHP
深入解析PHP的Laravel框架中的event事件操作
2016/03/21 PHP
PHP命名空间用法实例分析
2019/09/04 PHP
Jquery 组合form元素为json格式,asp.net反序列化
2009/07/09 Javascript
JS 日期验证正则附asp日期格式化函数
2009/09/11 Javascript
jquery插件之easing使用
2010/08/19 Javascript
用innerhtml提高页面打开速度的方法
2013/08/02 Javascript
javascript实现十秒钟后注册按钮可点击的方法
2015/05/13 Javascript
javascript实现根据3原色制作颜色选择器的方法
2015/07/17 Javascript
第三章之Bootstrap 表格与按钮功能
2016/04/25 Javascript
Ubuntu 16.04 64位中搭建Node.js开发环境教程
2016/10/19 Javascript
微信小程序(应用号)开发新闻客户端实例
2016/10/24 Javascript
javascript基础知识讲解
2017/01/11 Javascript
JS 调试中常见的报错问题解决方法
2017/05/20 Javascript
详解在express站点中使用ejs模板引擎
2017/09/21 Javascript
ES6使用Set数据结构实现数组的交集、并集、差集功能示例
2017/10/31 Javascript
Vue2.x Todo之自定义指令实现自动聚焦的方法
2019/01/08 Javascript
微信公众号平台接口开发 菜单管理的实现
2019/08/14 Javascript
vue 动态表单开发方法案例详解
2019/12/02 Javascript
详解React中共享组件逻辑的三种方式
2021/02/02 Javascript
python进阶教程之循环相关函数range、enumerate、zip
2014/08/30 Python
Python处理RSS、ATOM模块FEEDPARSER介绍
2015/02/18 Python
Python cookbook(数据结构与算法)将多个映射合并为单个映射的方法
2018/04/19 Python
Windows下python3.7安装教程
2018/07/31 Python
Python中Numpy ndarray的使用详解
2019/05/24 Python
python获取点击的坐标画图形的方法
2019/07/09 Python
opencv调整图像亮度对比度的示例代码
2019/09/27 Python
python实现按键精灵找色点击功能教程,使用pywin32和Pillow库
2020/06/04 Python
Python 如何实现访问者模式
2020/07/28 Python
H5 meta小结(前端必看篇)
2016/08/24 HTML / CSS
一个C/C++编程面试题
2013/11/10 面试题
材料化学应届生求职信
2013/10/09 职场文书
《宋庆龄故居的樟树》教学反思
2014/04/07 职场文书
2015新年寄语大全
2014/12/08 职场文书