Django restframework 源码分析之认证详解


Posted in Python onFebruary 22, 2019

前言

最近学习了 django 的一个 restframework 框架,对于里面的执行流程产生了兴趣,经过昨天一晚上初步搞清楚了执行流程(部分方法还不太清楚),于是想详细的总结一下当来一个请求时,在该框架里面是如何执行的?

启动项目时

昨天在调试django时,发现在 APIView 中打的断点没有断下来,而是打在 View 中的断点断下来了,调试了很多次,最后发现,在 django 项目启动时,会首先加载 urls 中的文件,执行 views 中类的 as_view方法,其实是继承自 APIView 的,APIView 继承自 django 原生 View 的as_view 方法。

里面一个参数叫 pattern_name,对应的值是admin:auth_group_change,如下图所示:

Django restframework 源码分析之认证详解

目前还不清楚这里面的具体流程是什么,但是并不妨碍阅读之后的源码,在这只要清楚一点,在 Django 项目启动时,路由所对应的CBV里面的相关方法的内存地址已经获取到。这样做的好处就是提高效率,坏处可能有一点点,会提升性能的消耗。

具体路由和逻辑代码

在这里假设来一个 GET 请求,urls 和 views里面的代码如下:

# urls.py

url(r'^book/(?P<id>\d+)/', views.Book.as_view()),
# views.py
class Book(APIView):

  def dispatch(self, request, *args, **kwargs):
    return super().dispatch(request, *args, **kwargs)

  def get(self, request, id):

    response = {'status': 100, 'msg': None}

    book = models.Book.objects.filter(pk=id).first()
    book_ser = BookSerib(book, many=False)
    print('book_ser.data', book_ser.data)
    response['books'] = book_ser.data
    response['msg'] = '获取图书成功'
    print('response', response)
    return Response(response)

urls 里面就是一个典型的 CBV 的路由配置,在 views 中一个是路由分发方法,一个是获取单本图书信息(通过 id)。

as_view 具体执行流程

在项目启动时,相应的函数内存地址已经获取到,那么具体是怎么获取到的呢?

在上面的代码中可以看到 Book 类是继承自 APIView 类的,所以在路由配置里面执行的 as_view 方法如果 Book 类没有重写,那么执行的就是按照 mro 列表顺序查找到的第一个方法,在这里执行的是 APIView 类中的 as_view 方法。

查看该源码如下:

Django restframework 源码分析之认证详解

APIView 类的父类是 View 类,查看该类的 as_view 方法,源码如下:

Django restframework 源码分析之认证详解

具体 as_view 就是将 view 函数的内存地址返回,以便请求来时直接调用。

initkwargs 这个参数应该是由 django 内部传的一些参数,如下所示:

Django restframework 源码分析之认证详解

请求到来时

因为经过 django 先执行了 as_view 返回 view 的内存地址,所以会直接执行 view 函数,如下:

Django restframework 源码分析之认证详解

在这里该 self 由于是 继承自 APIView 类的 Book 类的对象,所以 dispatch 方法首先去自身找,之后去父类找,在 APIView 类中找到 dispatch 方法,源码如下:

Django restframework 源码分析之认证详解

initialize_request方法:

源码如下:

Django restframework 源码分析之认证详解

在实例化 Request 对象时, authenticators 参数需要在认证时使用,所以先把这个参数的值找出来。步骤如下:

调用 self.get_authenticators

Django restframework 源码分析之认证详解

找到 self.authentication_classes

Django restframework 源码分析之认证详解

找到 api_settings,才能找到DEFAULT_AUTHENTICATION_CLASSES

Django restframework 源码分析之认证详解

DEFAULT和IMPORT_STRINGS参数

DEFAULT参数

Django restframework 源码分析之认证详解

IMPORT_STRINGS参数

Django restframework 源码分析之认证详解

实例化 APISettings 对象

Django restframework 源码分析之认证详解

通过__getattr__方法获取值

Django restframework 源码分析之认证详解

执行perform_import方法

Django restframework 源码分析之认证详解

执行import_from_string

Django restframework 源码分析之认证详解

执行import_module

Django restframework 源码分析之认证详解

执行_bootstrap._gcd_import

Django restframework 源码分析之认证详解

执行_sanity_check

Django restframework 源码分析之认证详解

_sanity_check返回,执行_find_and_load方法

Django restframework 源码分析之认证详解

所以通过__getattr__的到的是一个列表,里面是两个类,分别是[rest_framework_authentication_SessionAuthentication, rest_framework_authentication_BasicAuthentication]

到这里,initialize_request方法执行结束,得到一个经过 Request 类实例化的 request 对象,该对象里面含有原生 request 对象,可以通过 request._request 取到。

initial 方法:

源码如下:

Django restframework 源码分析之认证详解

这里传入的 request 参数是经过 Request 封装后的参数

执行get_format_suffix

Django restframework 源码分析之认证详解

执行完这个方法, self_format_kwarg = None

执行perform_content_negotiation

Django restframework 源码分析之认证详解

执行self.get_renders

Django restframework 源码分析之认证详解

执行self.get_content_negotiator

Django restframework 源码分析之认证详解

执行 conneg.select_renderer方法

Django restframework 源码分析之认证详解

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python输出带颜色的字符串实例
Oct 10 Python
TensorFlow实现卷积神经网络CNN
Mar 09 Python
Django跨域请求问题的解决方法示例
Jun 16 Python
Python3实现腾讯云OCR识别
Nov 27 Python
Python动态语言与鸭子类型详解
Jul 01 Python
python使用装饰器作日志处理的方法
Jul 11 Python
python2 中 unicode 和 str 之间的转换及与python3 str 的区别
Jul 25 Python
matplotlib实现显示伪彩色图像及色度条
Dec 07 Python
python小项目之五子棋游戏
Dec 26 Python
Python列表解析操作实例总结
Feb 26 Python
Python字符串格式化常用手段及注意事项
Jun 17 Python
Python自动化之UnitTest框架实战记录
Sep 08 Python
运用Python的webbrowser实现定时打开特定网页
Feb 21 #Python
Python3爬虫之自动查询天气并实现语音播报
Feb 21 #Python
python 自动批量打开网页的示例
Feb 21 #Python
Python3利用Dlib实现摄像头实时人脸检测和平铺显示示例
Feb 21 #Python
Python利用itchat库向好友或者公众号发消息的实例
Feb 21 #Python
python使用wxpy轻松实现微信防撤回的方法
Feb 21 #Python
Python开发网站目录扫描器的实现
Feb 21 #Python
You might like
如何解决CI框架的Disallowed Key Characters错误提示
2013/07/05 PHP
php安装xdebug/php安装pear/phpunit详解步骤(图)
2013/12/22 PHP
php保存信息到当前Session的方法
2015/03/16 PHP
PHP 记录访客的浏览信息方法
2018/01/29 PHP
php 下 html5 XHR2 + FormData + File API 上传文件操作实例分析
2020/02/28 PHP
php7 错误处理机制修改实例分析
2020/05/25 PHP
User Scripts: Video Download by User Scripts
2007/05/14 Javascript
最近项目写了一些js,水平有待提高
2009/01/31 Javascript
javascript 验证日期的函数
2010/03/18 Javascript
最简单的js图片切换效果实现代码
2011/09/24 Javascript
jquery中使用$(#form).submit()重写提交表单无效原因分析及解决
2013/03/25 Javascript
自编jQuery插件实现模拟alert和confirm
2014/09/01 Javascript
基于jQuery实现自动轮播旋转木马特效
2015/11/02 Javascript
JavaScript tab选项卡插件实例代码
2016/02/23 Javascript
vue-prop父组件向子组件进行传值的方法
2018/03/01 Javascript
基于Bootstrap下拉框插件bootstrap-select使用方法详解
2018/08/07 Javascript
Element UI框架中巧用树选择器的实现
2018/12/12 Javascript
Vue 微信端扫描二维码苹果端却只能保存图片问题(解决方法)
2020/01/19 Javascript
使用 Opentype.js 生成字体子集的实例代码详解
2020/05/25 Javascript
[01:14]DOTA2亚洲邀请赛小组赛赛前花絮
2017/03/27 DOTA
[36:05]完美世界DOTA2联赛循环赛 Forest vs DM 第一场 11.06
2020/11/06 DOTA
Python中文件I/O高效操作处理的技巧分享
2017/02/04 Python
Python多线程爬虫实战_爬取糗事百科段子的实例
2017/12/15 Python
Python 3.6 读取并操作文件内容的实例
2018/04/23 Python
对python 通过ssh访问数据库的实例详解
2019/02/19 Python
Python math库 ln(x)运算的实现及原理
2019/07/17 Python
Python可视化工具如何实现动态图表
2020/10/23 Python
台湾最大银发乐活百货:乐龄网
2018/05/21 全球购物
Shein英国:女性时尚网上商店
2019/04/10 全球购物
护理自我鉴定范文
2013/10/06 职场文书
《记承天寺夜游》教学反思
2014/02/16 职场文书
小学语文国培感言
2014/03/04 职场文书
学习雷锋精神演讲稿
2014/05/10 职场文书
工商管理专业毕业生求职信
2014/05/26 职场文书
党支部对照检查材料
2014/08/25 职场文书
pytorch 权重weight 与 梯度grad 可视化操作
2021/06/05 Python