蓝图
在一个 Flask 应用项目中,如果业务视图过多,可否将以某种方式划分出的业务单元单独维护,将每个单元用到的视图、静态文件、模板文件等独立分开 ?
例如从业务角度上,可将整个应用划分为用户模块单元、商品模块单元、订单模块单元,如何分别开发这些不同单元,并最终整合到一个项目应用中?
在 Flask 中,使用蓝图 Blueprint 来分模块组织管理。
蓝图实际可以理解为是一个存储一组视图方法的容器对象,其具有如下特点:
- 一个应用可以具有多个 Blueprint
- 可以将一个 Blueprint 注册到任何一个未使用的 URL 下比如
/user
、/goods
- Blueprint 可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的
- 在一个应用初始化时,就应该要注册需要使用的 Blueprint
但是一个 Blueprint 并不是一个完整的应用,它不能独立于应用运行,而必须要注册到某一个应用中。
使用方式
使用蓝图可以分为三个步骤
1、创建一个蓝图对象
# 1. 创建蓝图对象
auth_bp = Blueprint('auth', __name__)
2、在这个蓝图对象上进行操作,注册路由,指定静态文件夹,注册模版过滤器
# 2. 使用蓝图对象挂载路由
@auth_bp.route('/auth/login')
def login():
return 'user_login'
@auth_bp.route('/auth/logout')
def logout():
return 'user_logout'
3、在应用对象上注册这个蓝图对象
# 3. 将蓝图对象挂载的 app 对象
app.register_blueprint(auth_bp)
单文件蓝图
可以将创建蓝图对象与定义视图放到一个文件中 。
目录(包)蓝图
对于一个打算包含多个文件的蓝图,通常将创建蓝图对象放到 Python 包的__init__.py
文件中
--- project # 工程目录
|------ main.py # 启动文件
|------ auth #用户蓝图
| |--- __init__.py # 此处创建蓝图对象
| |--- passport.py
| |--- profile.py
| |--- ...
|
|------ goods # 商品蓝图
| |--- __init__.py
| |--- ...
|...
蓝图的 url 前缀
在应用中注册蓝图时使用 url_prefix
参数指定
admin_bp = Blueprint('admin', __name__)
@admin_bp.route('/user')
def user_profile():
return '用户后台页面'
# 给路由添加前缀 admin_bp 下的路由全部都会加前缀
# /user --> /admin/user
app.register_blueprint(admin_bp, url_prefix='/admin')
路由匹配
为了便于将请求分发到对应的视图函数,程序实例中存储了一个路由表(app.url_map),其中定义了URL规则和视图函数的映射关系。当请求发来后,Flask会根据请求报文中的URL(path部分)来尝试与这个表中的 所有URL规则进行匹配,调用匹配成功的视图函数。如果没有找到匹配的 URL规则,Flask会自动返回 404错误响应(Not Found,表示资源未找到)。
使用flask routes命令可以查看程序中定义的所有路由,这 个列表由app.url_map解析得到:
(venv) D:>flask routes
Endpoint Methods Rule
-------- ------- -----------------------
index GET /
static GET /static/<path:filename>
在输出的文本中,我们可以看到每个路由对应的端点(Endpoint)、 HTTP 方法(Methods)和 URL 规则(Rule),其中 static 端点是 Flask 添加的 特殊路由,用来访问静态文件。