使用蓝图 blueprint
1. 一个最小的应用
蓝图(blueprint)技术,可以实现flask应用的模块划分。
在组织flask代码时,有功能式架构和分区式架构两种模式,使用蓝图,可以让项目架构更有层次,模块划分更便捷..
下面这个示例非常的小巧,但是能提供的内容非常的少。
在实际开发大型的flask应用时,我们会需要划分许多模块,提供很多的功能 。
1 2 3 4 5 6 7 8 9 10 11 12
| from flask import Flask app = Flask(__name__)
@app.route('/') def hello_world(): return 'Hello World!'
if __name__ == '__main__': app.run(port=5678)
|
2. 一个稍大点的flask应用
下面的flask应用里,有一个user模块专门提供和用户有关的功能。
例如用户注册,登录,登出,修改密码。
还有一个admin模块,用来做后台管理。
这个示例展示了如何在一个脚本里编写所有的模块,但这些视图函数并没有具体的实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| from flask import Flask app = Flask(__name__)
@app.route('/') def hello_world(): return 'Hello World!'
@app.route('/user/register') def register(): return 'register'
@app.route('/user/login') def login(): return 'login'
@app.route('/user/modify_password') def modify_password(): return 'modify_password'
@app.route('/admin/alluser') def alluser(): return 'alluser'
@app.route('/admin/deluser') def deluser(): return 'deluser'
if __name__ == '__main__': app.run(port=5678)
|
和最小的flask应用相比,这个应用多了两个模块,5个视图函数,但还是非常小。
在实践项目中,子模块和视图函数会更多。因此,我们应该尽量避免将这些都写在同一个脚本中。
否则,这个脚本会非常的大,难以维护。
3. BluePrint 蓝图技术
蓝图技术,可以帮助你实现flask应用的模块划分。如果不划分模块或者模块划分不合理,会带来很多麻烦。
第2小节的应用划分出两个模块,划分后,项目结构不再是一个单一的脚本,一个模块拥有一个属于自己的文件目录,与之相关的代码都将写在这里,项目结构如下:
1 2 3 4 5 6 7 8
| blue-example/ ├── admin │ ├── __init__.py │ └── views.py ├── app.py └── user ├── __init__.py └── views.py
|
以下展示脚本内容
3.1 app.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| from flask import Flask app = Flask(__name__)
@app.route('/') def hello_world(): return 'Hello World!'
from admin import admin_blue from user import user_blue
app.register_blueprint(admin_blue) app.register_blueprint(user_blue)
if __name__ == '__main__': app.run(port=5678)
|
app.py 代码干净整洁
3.2 user模块
user/init.py
1 2 3 4
| from flask import Blueprint
user_blue = Blueprint('user', __name__, url_prefix='/user') from . import views
|
user/views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| from user import user_blue
from user import user_blue
@user_blue.route('/register') def register(): return 'register'
@user_blue.route('/login') def login(): return 'login'
@user_blue.route('/modify_password') def modify_password(): return 'modify_password'
|
3.3 admin
admin/init.py
1 2 3 4 5
| from flask import Blueprint
admin_blue = Blueprint('admin', __name__, url_prefix='/admin') from . import views
|
admin/views.py
1 2 3 4 5 6 7 8 9 10 11 12
| from admin import admin_blue
@admin_blue.route('/alluser') def alluser(): return 'alluser'
@admin_blue.route('/deluser') def deluser(): return 'deluser'
|
第3小节的项目代码,多了一些模块的划分和文件目录。
看上去,比第2小节的代码变复杂了些,但这种“复杂”是值得的, 能得到整个项目清晰的结构,很好的控制了单个脚本的代码规模。
4. 两种代码组织形式
蓝图在组织flask代码时,有两种形式
- 功能式架构
- 分区式架构
前面所展示的就是功能式架构,一个功能,一个模块组织成一个蓝图,他们共用相同的静态资源,静态资源放在static目录下。
本文所举实例太简单,因此没有创建静态资源,功能式架构类似于下面的结构
1 2 3 4 5 6 7 8 9 10 11 12
| __init__.py static/ templates/ home/ control_panel/ admin/ views/ __init__.py home.py control_panel.py admin.py models.py
|
home, control_panel,admin 都是蓝图,他们共用static和 templates。
分区式架构,适用于子模块有特殊需要的情况,在创建蓝图构造Blueprint对象时,可以指定static和templates。
结构示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| yourapp/ __init__.py admin/ __init__.py views.py static/ templates/ home/ __init__.py views.py static/ templates/ control_panel/ __init__.py views.py static/ templates/ models.py
|
试想,如果admin, home, control_panel有各自不同的页面样式和风格,那么他们就需要不同的静态资源,css, javascript,每个模块拥有各自的静态资源就是一个合理的选择。这样组织,还有一个好处,一个模块,或者说一个蓝图拥有自身全部的资源,包括static和templates,那么它可以很容易从一个项目里拆分出来放在另一个项目中使用。
具体使用哪种组织架构,并没有强制要求,完全是开发人员随心所欲的,重要的是从项目管理的角度出发,哪一种更利于你所项目的管理,就用哪一种。