当前位置:网站首页>【flask高级】从源码深入理解flask路由之endpoint
【flask高级】从源码深入理解flask路由之endpoint
2022-07-23 14:32:00 【馆主阿牛】
个人简介
- 作者简介:大家好,我是阿牛,全栈领域新星创作者。
- 博主的个人网站:阿牛的博客小屋
- 支持我:点赞+收藏️+留言
- 系列专栏:flask框架快速入门
- 格言:要成为光,因为有怕黑的人!

前言
很多人对flask的路由机制有错误的理解,这节我将从源码分析,带你深入了解flask的路由机制。
flask路由分析
有很多人对我们的flask有错误的理解,认为我们的url直接对应的是视图函数,表面上看起来确实没有什么问题,但恰恰你忽略掉了我们的endpoint!
从逻辑上来说,我们知道url后,直接对应我们的视图函数是没有问题的,这是正向的,那我们反向从视图函数到我们的url就不太方便了,因此,我们的endpoint可以起到反向构建url的作用。

url_for与endpoint反向构建url
下面我大概说一下endpoint是如何反向构建URL的,其实这个endpoint和url_for息息相关,url_for正好是反向构建URL的。
如下:
from flask import Flask,url_for
app = Flask(__name__)
@app.route('/', endpoint='my_index')
def index():
return 'index page'
@app.route('/hello')
def hello():
return url_for('.my_index', _external=True)
app.run(debug=True)

注:
1.在url_for 反转时,接受一个endpoint或者函数名为参数(如果是endpoint,endpoint前面需要加个点),返回对应的url地址(可看源码)。
2.在前端页面如果使用url_for的时候,也需要加上点,如:{ { url_for(‘.my_index’) }}。
3._external=True 如果设置为True,则生成一个绝对路径URL,如上图。
反向构建在这里顺带提一下,接下来我们回到正题,看下面这两段代码:
from flask import Flask
app = Flask(__name__)
# @app.route('/user')
#我们的装饰器里也有endpoint参数,正常情况下我们就省略了,省略后默认值为函数名
@app.route("/user",endpoint="user")
def user():
return "a niu"
app.run(debug=True)
我们的装饰器里也有endpoint参数,正常情况下我们就省略了,省略后默认值为函数名。
我们再看下面这段代码:
from flask import Flask
app = Flask(__name__)
# @app.route("/user",endpoint="user")
def user():
return "a niu"
app.add_url_rule(rule="/user",endpoint="user",view_func=user)
app.run(debug=True)

依旧没有问题,由此可见@app.route()和app.add_url_rule()是等价的,实际上装饰器底层也就干了这么个事。
add_url_rule()这个方法有四个参数:
1.rule:这个参数很简单,就是匹配的路由地址
2.endpoint:这个参数就是我今天重点要讲的,endpoint。
3.view_func:这个参数就是我们写的视图函数
4.**options:可变数量的参数
app.add_url_rule(rule="/user",endpoint="user",view_func=user,methods=['GET'])
那么接下来我们就从装饰器入手去看一看源码,看源码有一种比较好的方法就是断点调试,你们可以去试试,我们可以由此进入flask内部,一行一行执行!

给装饰器打上断点,右键启动调试,然后将鼠标移到route上点击,然后ctrl + B进入我们的源码

我们可以看到装饰器的底层确实就是add_url_rule,这里的self我们从下面的变量看,就是我们的app对象。

然后多点击几次上图的步入之后,我们会看到上图我用红框框起来的部分,这部分代码我们可以看到就是在对endpoint是否为空做判断,为空则endpoint为视图函数名。
我们继续不断步入
可以看到最终将我们的rule添加到了url_map中。

然后可以看到,将我们的视图函数存到了views_functions中的字典里,每一个键正好是endpoint,正好形成了映射。

然后我们将光标点到这一行,点击下面的运行到光标处,此时我们要研究的就运行结束了。
然后点开self,找到url_map,看看最终url_map里是啥?

可以看到url_map是个列表,存的是rule-endpoint映射,而上面我们也分析了endpoint和view_func映射,是个字典。
这里我们可以在代码中打印出我们的url_map和view_functions来清楚看看:
from flask import Flask
app = Flask(__name__)
# @app.route('/user')
# 我们的装饰器里也有endpoint参数,正常情况下我们就省略了,省略后默认值为函数名
@app.route("/user",endpoint="user")
def user():
return "a niu"
if __name__ == '__main__':
print(app.url_map)
print(app.view_functions)
app.run()

跟看源码分析的一样!
总结
每个应用程序app都有一个view_functions,这是一个字典,存储endpoint-view_func键值对。add_url_rule的第一个作用就是向view_functions中添加键值对(这件事在应用程序run之前就做好了)
每个应用程序app都有一个url_map,它是一个Map类(具体实现在werkzeug/routing.py中),里面包含了一个列表,列表元素是Rule的实例,即url到endpoint的映射(werkzeug/routing.py中)。add_url_rule的第二个作用就是向url_map中添加Rule的实例(它也是在应用程序run之前就做好了)
结语
如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。
边栏推荐
- 搜索二叉树——寻找节点,插入节点,删除节点
- Detailed explanation of SQL error reporting and blind annotation
- Browser homology policy
- Detailed explanation of SQL bool blind note and time blind note
- 【Flutter -- 布局】线性布局(Row 和 Column)
- 新零售电商平台怎么做?才能实现传统零售企业数字化转型?
- Pymoo学习 (1):基本概念
- quota命令详细拓展使用方法,RHEL 7中quota命令搭载方法!磁盘容量配额!
- Description and usage of Axi interconnect IP core
- oracle 数据库 11C 之后版本使用 memory_target 自动内存管理
猜你喜欢
随机推荐
Win11如何添加图片3D效果?Win11添加图片3D效果的方法
食品安全|火腿肠午餐肉,真有说的那么不堪?
通过SSH方式访问内网RDS+mysql
PWN entry (3) heap
股票历史数据下载接口汇总(动态更新)
详解一次SQL优化
Pinduoduo app product details interface to obtain activity_ ID value (pinduoduo activity_id interface)
【Flutter -- 布局】弹性布局(Flex 和 Expanded)
死磕遞歸1:遞推公式
Keil errors and solutions (1): fcarm - output name not specified, please check 'options for target - Utilities‘
General paging implementation
iphone 无法打开openv**文件的解决方案
蓝桥杯真题:卡片[通俗易懂]
【Flutter -- 布局】线性布局(Row 和 Column)
Sorting - introduction, code ideas, usage suggestions, code implementation -1
keras——accuracy_ Score formula
First deep search and first wide search of graph (realized by three methods)
Fundamentals of C language -- 2-6 pointers, arrays and sizeof operators
VSCode PIO创建工程失败分析和解决办法
AXI interconnect IP核的说明及用法









