Flask 蓝图机制及应用
我们都知道 flask 是一个轻量级的 web 框架,相对于其他同类型框架更为灵活、轻便、安全且容易上手。开发者可以随意编写自己想要的项目结构,同时还有很多的第三方库供君选择。但是灵活的同时也带来了相应的问题,比如对很多初学者来说,建的项目结构混乱,不易维护,还有经典的循环导入等问题
循环导入问题
很多初学者喜欢将启动文件和多个路由写在同一个文件中,例如以下代码:

这样一旦随着视图函数的增多,代码的可维护性会变得越来越差。所以有必要对视图函数进行拆分。
我们将其拆分成两个文件:run.py 和 view.py,其中 run.py 作为程序的启动文件,因为要将路由注册到 flask 核心对象上,所以在 view.py 中需要导入核心对象,同时 run.py 中要导入 view。最终,代码和项目结构如下所示:

run.py

view.py

但是当我启动程序,在浏览器中输入地址 http://127.0.0.1:5000/add?name=Jerry 之后,报 404 Not Found。

这是为什么呢? 为什么在 view.py 中注册的视图函数找不到呢? 原因就是因为循环导入,我们在 run.py 中导入了 view, 同时又在 view.py 中导入了 run.py 中的 app!最终导致什么结果呢,我们通过调试来发现吧!
详解循环导入
启动 run, 第一次实例化一个 Flask 的核心对象 app,执行到导入 view 代码,这是第一个关键点 1!

- 在 view.py 中,执行到导入 app 的代码,转而去执行 run.py 中的代码

- 可以看到程序又再一次执行了 run.py 中的代码,同时又一次实例化了一个 Flask 的核心对象,为了区分,我们将它称为 app2,这是第二个关键点 2 !

由于,本次执行 _ name _ != _ main _,所以并不会执行 app.run()。那么程序将继续执行 view.py 中剩余代码

可以看到,程序将相关的路由函数注册到了 app2 上面!
当 view.py 中代码执行完成之后,将继续执行 run.py 中后面的代码。也就是前面提到的关键点 1 之后的相关代码!

此时将路由函数 index 注册到了 app 上面,同时 _ name _ == _ main _,所以 app.run() 启动成功!
通过上面的分析,总结如下:
整个过程初始化了两次 Flask 核心对象,app 和 app2
view 中的视图函数注册在 app2 上面
index 视图函数注册了两次,第一次注册到 app2,最后一次注册 app 上面
最终启动的核心对象是 app
现在你应该明白了,view.py 中的视图函数注册的 app 和最终启动的 app 不是同一个,所以最终导致找不到视图函数!为了能有个更直观的感受,我们可以将 app 的内存地址打印出来,这样更加一目了然!

可以看到,注册和启动的 app 不是同一个!
蓝图
解决方案:Flask 给我们提供一种机制,蓝图(Blueprint)。
蓝图就是一个存储操作路由映射方法的容器,主要用来实现客户端请求和 URL 相互关联的功能。蓝图类似 Django 中的 app,两者的功能非常相似,帮助我们实现模块化应用的功能。
在 Flask 中可以创建多个蓝图,代表不同的功能模块。比如,上面代码中的 web 文件夹就能作为一个蓝图,另外用户相关的功能模块 user 也能创建一个相应的蓝图

蓝图应用
了解蓝图的相关功能之后,我们正式通过蓝图来解决以上问题。
首先在web/_ init _.py 文件中创建蓝图:

- 蓝图创建完之后,在 view.py 中导入对应的蓝图,并将视图函数注册到蓝图中,改造完之后如下:

我们自始至终都要清楚,Flask 中的相关功能插件以及视图函数最终都要注册到核心对象上面,所以蓝图也是要注册到核心对象上面。同时要了解到,当项目功能较多,用的插件也很多的时候,核心对象的初始化以及蓝图、第三方插件的注册的相关代码会很多,这时候也要对代码进行分离。
所以在 app/_ init _.py 文件中做核心对象的初始化,同时将蓝图注册到核心对象上。代码如下:

同时在启动文件 run.py 记得导入 app 核心对象,修改后代码如下:

再次启动,我们可以看到,因为一个是蓝图,一个是 app 两者是不一致的。

验证结果
运行之后,我们在浏览器中或者用代码来验证一下:
GET 请求

POST 请求

作者:华为云享开发者
Flask 蓝图机制及应用的更多相关文章
- Flask 蓝图(Blueprint)
蓝图使用起来就像应用当中的子应用一样,可以有自己的模板,静态目录,有自己的视图函数和URL规则,蓝图之间互相不影响.但是它们又属于应用中,可以共享应用的配置.对于大型应用来说,我们可以通过添加蓝图来扩 ...
- flask 蓝图
转自:http://spacewander.github.io/explore-flask-zh/7-blueprints.html 蓝图 什么是蓝图? 一个蓝图定义了可用于单个应用的视图,模板,静态 ...
- Flask蓝图目录、Flask-SQLAlchemy、Flask-Script、Flask-Migrate
一.Flask蓝图目录 我们之前写的Flask项目都是自己组织的目录结构,其实Flask官方有其推荐的目录结构,以下就是一个符合官方推荐的Flask小型应用的项目结构目录示例,如下: 如图,这就是我们 ...
- Flask蓝图的增删改查
怎样用flask蓝图来实现增删改查呢?请看下面的内容 这是我们的目录结构 从图中可以看出每一个功能都有一个各自的文件夹 首先我们要自己先来创建一个数据,在Flask_data.py中写入如下内容: S ...
- Flask蓝图基本使用
Flask蓝图基本使用 Flask通过使用蓝图将视图函数模块化,使应用显得更加规整 比如我们的应用的视图函数包括用户相关和文章相关,那么我们可以通过建立两个py文件分别存储两类视图函数 user.py ...
- Flask蓝图遇到的问题
欢迎加入python学习交流群 667279387 最近在使用flask开发一个业余学习项目,由于之前都是"小打小闹",整个程序都是放在一个文件夹里面的,也没有注意这个问题.这次项 ...
- Flask蓝图Blueprint和特殊装饰器
Flask 中的 蓝图 Blueprint 不能被run的flask实例:相当于django中的app01 应用 蓝图作用:功能隔离 路由隔离 Blueprint就是 一个不能run的flask 蓝图 ...
- Flask 蓝图进行路由分发.md
Flask 蓝图进行路由分发 Flask虽然说是一个轻型web框架,但也总不能用一个py文件写完全部view吧,所以我们要把路由分到不同的py文件中.这就需要用到蓝图了. 一 创建一个py文件 用于处 ...
- Flask 蓝图(Blueprint)使用方式解析
Flask蓝图提供了模块化管理程序路由的功能,使程序结构清晰.简单易懂.下面分析蓝图的使用方法 假如说我们要为某所学校的每个人建立一份档案,一个很自然的优化方式就是这些档案如果能分类管理,就是说假如分 ...
随机推荐
- CSPS模拟 55
没睡醒就考试,蓝绶 考试前我在擦眼镜 好像总也擦不干净? 就像石乐志一样一直地在擦 cbx捅了我几下,好像想说什么? 没睡醒,不理 终于擦完了! 雾草要考试? T1 联 先离散化,再正面上线段树 em ...
- 通俗易懂了解Vue组件的通信方式
1.前言 Vue框架倡导组件化开发,力求将一个大的项目拆分成若干个小的组件,就如同我们小时玩堆积木一样,一个大房子是由若干个小积木组成.组件化开发最大问题就是组件之间数据能够流通,即组件之间能够通信. ...
- PHP创建文件命名中文乱码解决的方法
PHP创建文件命名中文乱码解决的方法 <pre>iconv('utf-8', 'gbk', $dir); </pre> 因为系统环境是gbk 所以里面的字符也要gbk 编码一致 ...
- Unity中用Mesh画一个圆环
Probuider 前几天在做一个小项目的时候,用到了Unity自带的一个包ProBuilder其中的Arch生成1/4圆. 挺好玩的,可以在直接Unity中根据需要用Mesh定制生成图形,而不用建模 ...
- springboot~高并发下耗时操作的实现
高并发下的耗时操作 高并发下,就是请求在一个时间点比较多时,很多写的请求打过来时,你的服务器承受很大的压力,当你的一个请求处理时间长时,这些请求将会把你的服务器线程耗尽,即你的主线程池里的线程将不会再 ...
- centos6升级openssh至7.9
1.为了防止升级失败登陆不了,所以需要安装telnet mkdir /root/ssh_updateyum install -y telnet-serveryum install -y xinetd ...
- U盘安装centos7 系统卡在 starting dracut initqueue hook
U盘安装centos7启动过程中出现: [ok] Reached target Basic System 或者 [ok] starting dracut initqueue hook 下面是我解决的过 ...
- SqlServer2005 查询 第四讲 in
今天我们来说sql中的命令参数in in --in用于查询某个字段的指定的值的记录信息 注意一下:--对或(or)取反是并且(and),对并且(and)取反是或(or 数据库中不等于表示有两种:!= ...
- 领扣(LeetCode)删除注释 个人题解
给一个 C++ 程序,删除程序中的注释.这个程序source是一个数组,其中source[i]表示第i行源码. 这表示每行源码由\n分隔. 在 C++ 中有两种注释风格,行内注释和块注释. 字符串// ...
- linux命令指令
1.ls显示目录内容 -a 显示目录下所有文件 -l 显示详细信息 ls *.c 列出当前目录所有的.c文件 2.uname -a 查看内核版本 3.whoami 查看谁登陆虚拟机 4.cd 切 ...