Flask[认同]

Flask[认同]

七月 07, 2023

使用蓝图 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!'


# user模块
@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'


# admin模块
@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


# user模块
from user import user_blue


# user模块
@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模块
@admin_blue.route('/alluser')
def alluser():
return 'alluser'


@admin_blue.route('/deluser')
def deluser():
return 'deluser'

第3小节的项目代码,多了一些模块的划分和文件目录。

看上去,比第2小节的代码变复杂了些,但这种“复杂”是值得的, 能得到整个项目清晰的结构,很好的控制了单个脚本的代码规模。

4. 两种代码组织形式

蓝图在组织flask代码时,有两种形式

  1. 功能式架构
  2. 分区式架构

前面所展示的就是功能式架构,一个功能,一个模块组织成一个蓝图,他们共用相同的静态资源,静态资源放在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,那么它可以很容易从一个项目里拆分出来放在另一个项目中使用。

具体使用哪种组织架构,并没有强制要求,完全是开发人员随心所欲的,重要的是从项目管理的角度出发,哪一种更利于你所项目的管理,就用哪一种。