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对象及面向对象技术详解
Jul 19 Python
Python正则表达式使用范例分享
Dec 04 Python
Django的信号机制详解
May 05 Python
简单谈谈Python中的json与pickle
Jul 19 Python
python使用KNN算法手写体识别
Feb 01 Python
django框架模板中定义变量(set variable in django template)的方法分析
Jun 24 Python
pybind11在Windows下的使用教程
Jul 04 Python
用sqlalchemy构建Django连接池的实例
Aug 29 Python
python requests证书问题解决
Sep 05 Python
python飞机大战 pygame游戏创建快速入门详解
Dec 17 Python
安装Anaconda3及使用Jupyter的方法
Oct 27 Python
python 利用 PIL 将数组值转成图片的实现
Apr 12 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 将bmp图片转为jpg等其他任意格式的图片
2009/06/21 PHP
PHP 身份验证方面的函数
2009/10/11 PHP
PHP查看当前变量类型的方法
2015/07/31 PHP
PHP中addslashes()和stripslashes()实现字符串转义和还原用法实例
2016/01/07 PHP
PHP延迟静态绑定使用方法实例解析
2020/09/05 PHP
JavaScript 学习笔记(十四) 正则表达式
2010/01/22 Javascript
基于javascript的JSON格式页面展示美化方法
2014/07/02 Javascript
了不起的node.js读书笔记之例程分析
2014/12/22 Javascript
微信小程序开发之圆形菜单 仿建行圆形菜单实例
2016/12/12 Javascript
BootStrap 动态表单效果
2017/06/02 Javascript
Vue单文件组件的如何使用方式介绍
2017/07/28 Javascript
js实现鼠标拖拽多选功能示例
2017/08/01 Javascript
分享Bootstrap简单表格、表单、登录页面
2017/08/04 Javascript
js 获取json数组里面数组的长度实例
2017/10/31 Javascript
解决vue2.0动态绑定图片src属性值初始化时报错的问题
2018/03/14 Javascript
微信小程序上传帖子的实例代码(含有文字图片的微信验证)
2020/07/11 Javascript
[01:14:55]EG vs Spirit Supermajor 败者组 BO3 第三场 6.4
2018/06/05 DOTA
python提取页面内url列表的方法
2015/05/25 Python
python实现拓扑排序的基本教程
2018/03/11 Python
python实现简易通讯录修改版
2018/03/13 Python
Python函数装饰器常见使用方法实例详解
2019/03/30 Python
Python机器学习算法库scikit-learn学习之决策树实现方法详解
2019/07/04 Python
Python中zip()函数的简单用法举例
2019/09/02 Python
Python多线程:主线程等待所有子线程结束代码
2020/04/25 Python
Keras搭建自编码器操作
2020/07/03 Python
Jmeter调用Python脚本实现参数互相传递的实现
2021/01/22 Python
详解如何使用rem或viewport进行移动端适配
2020/08/14 HTML / CSS
EVE LOM英国官网:全世界最好的洁面膏
2017/10/30 全球购物
缓解脚、腿和背部疼痛:Z-CoiL鞋
2019/03/12 全球购物
简短证婚人证婚词
2014/01/09 职场文书
学习决心书
2014/03/11 职场文书
企业法人代表任命书
2014/06/06 职场文书
党员公开承诺书2015
2015/01/21 职场文书
2015年世界环境日演讲稿
2015/03/18 职场文书
清洁工工作总结
2015/08/11 职场文书
Opencv中cv2.floodFill算法的使用
2021/06/18 Python