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连接mysql数据库示例(做增删改操作)
Dec 31 Python
记录Django开发心得
Jul 16 Python
探究Python中isalnum()方法的使用
May 18 Python
python获取文件扩展名的方法
Jul 06 Python
Django实现分页功能
Jul 02 Python
对python周期性定时器的示例详解
Feb 19 Python
python 怎样将dataframe中的字符串日期转化为日期的方法
Sep 26 Python
python 字段拆分详解
Dec 17 Python
Pytorch对Himmelblau函数的优化详解
Feb 29 Python
PyInstaller将Python文件打包为exe后如何反编译(破解源码)以及防止反编译
Apr 15 Python
python matplotlib工具栏源码探析二之添加、删除内置工具项的案例
Feb 25 Python
PySwarms(Python粒子群优化工具包)的使用:GlobalBestPSO例子解析
Apr 05 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
Session保存到数据库的php类分享
2011/10/24 PHP
PHP输出时间差函数代码
2013/01/28 PHP
浅析php数据类型转换
2014/01/09 PHP
PHP观察者模式定义与用法实例分析
2019/03/22 PHP
浅析Cookie中的Path与domain
2013/12/18 Javascript
jQuery(js)获取文字宽度(显示长度)示例代码
2013/12/31 Javascript
Angularjs 基础入门
2014/12/26 Javascript
jquery实现横向图片轮播特效代码分享
2015/11/19 Javascript
AngularJS基础 ng-list 指令详解及示例代码
2016/08/02 Javascript
JavaScript计算值然后把值嵌入到html中的实现方法
2016/10/29 Javascript
node.js报错:Cannot find module 'ejs'的解决办法
2016/12/14 Javascript
基于javascript处理nginx请求过程详解
2020/07/07 Javascript
vue-列表下详情的展开与折叠案例
2020/07/28 Javascript
使用Python进行稳定可靠的文件操作详解
2013/12/31 Python
python的绘图工具matplotlib使用实例
2014/07/03 Python
python实现马耳可夫链算法实例分析
2015/05/20 Python
解决pycharm 误删掉项目文件的处理方法
2018/10/22 Python
Python模拟百度自动输入搜索功能的实例
2019/02/14 Python
Python符号计算之实现函数极限的方法
2019/07/15 Python
python数据库开发之MongoDB安装及Python3操作MongoDB数据库详细方法与实例
2020/03/18 Python
Python super()方法原理详解
2020/03/31 Python
pycharm 关掉syntax检查操作
2020/06/09 Python
BAILEY 44官网:美国制造的女性服装
2019/07/01 全球购物
Otiumberg官网:英国半精致珠宝品牌
2021/01/16 全球购物
面料业务员岗位职责
2013/12/26 职场文书
施工资料员岗位职责
2014/01/06 职场文书
大学生表扬信范文
2014/01/09 职场文书
共产党员公开承诺书
2014/03/25 职场文书
高中竞选班长演讲稿
2014/04/24 职场文书
银行求职自荐书
2014/06/25 职场文书
2015届大学生就业推荐表自我评价
2014/09/27 职场文书
公司2014年度工作总结
2014/12/10 职场文书
生鲜超市—未来中国最具有潜力零售业态
2019/08/02 职场文书
goland 清除所有的默认设置操作
2021/04/28 Golang
postgres之jsonb属性的使用操作
2021/06/23 PostgreSQL
MySQL如何使备份得数据保持一致
2022/05/02 MySQL