Skip to content

蓝图

在一个 Flask 应用项目中,如果业务视图过多,可否将以某种方式划分出的业务单元单独维护,将每个单元用到的视图、静态文件、模板文件等独立分开 ?

例如从业务角度上,可将整个应用划分为用户模块单元、商品模块单元、订单模块单元,如何分别开发这些不同单元,并最终整合到一个项目应用中?

在 Flask 中,使用蓝图 Blueprint 来分模块组织管理。

蓝图实际可以理解为是一个存储一组视图方法的容器对象,其具有如下特点:

  • 一个应用可以具有多个 Blueprint
  • 可以将一个 Blueprint 注册到任何一个未使用的 URL 下比如 /user/goods
  • Blueprint 可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的
  • 在一个应用初始化时,就应该要注册需要使用的 Blueprint

但是一个 Blueprint 并不是一个完整的应用,它不能独立于应用运行,而必须要注册到某一个应用中。

使用方式

使用蓝图可以分为三个步骤

1、创建一个蓝图对象

python
# 1. 创建蓝图对象  
auth_bp = Blueprint('auth', __name__)

2、在这个蓝图对象上进行操作,注册路由,指定静态文件夹,注册模版过滤器

python
# 2. 使用蓝图对象挂载路由  
@auth_bp.route('/auth/login')
def login():
    return 'user_login'


@auth_bp.route('/auth/logout')
def logout():
    return 'user_logout'

3、在应用对象上注册这个蓝图对象

python
# 3. 将蓝图对象挂载的 app 对象  
app.register_blueprint(auth_bp)

单文件蓝图

可以将创建蓝图对象与定义视图放到一个文件中 。

目录(包)蓝图

对于一个打算包含多个文件的蓝图,通常将创建蓝图对象放到 Python 包的__init__.py文件中

shell
--- project # 工程目录
  |------ main.py # 启动文件
  |------ auth  #用户蓝图
  |  |--- __init__.py  # 此处创建蓝图对象
  |  |--- passport.py  
  |  |--- profile.py
  |  |--- ...
  |
  |------ goods # 商品蓝图
  |  |--- __init__.py
  |  |--- ...
  |...

蓝图的 url 前缀

在应用中注册蓝图时使用 url_prefix 参数指定

python
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 添加的 特殊路由,用来访问静态文件。