前言
- 在前面的例子中,所有的页面处理逻辑都是放在同一个文件中,随着业务代码的增加,将所有代码都放在单个程序文件中是非常不合适的
- 不仅会让阅读代码变得困难,而且会给后期维护带来麻烦
- Flask 中使用蓝图,提供了模块化管理程序路由的功能,使程序结构更加清晰
蓝图简介
- 随着 Flask 程序越来越复杂,需要对程序进行模块化的处理
- 蓝图 (Blueprint) 是 Flask 程序的模块化处理机制
- 它是一个存储视图方法的集合
- Flask 程序通过 Blueprint 来组织 URL 以及处理请求
Blueprint 具有以下属性
- 一个项目可以具有多个 Blueprint
- Blueprint 可以单独拥有自己的模板、静态文件的目录
- 在应用初始化时,注册需要使用的 Blueprint
基本用法
功能概述
假设网站包含有如下 4 个页面:
页面 | 功能 | 处理函数 |
/news/society/ | 社会新闻版块 | society_news |
/news/tech/ | IT 新闻版块 | tech_news |
/products/car/ | 汽车产品版块 | car_products |
/products/baby/ | 婴幼儿产品版块 | baby_products |
- 前两个都是 /news 前缀,可以组成一个蓝图 news
- 后两个是 /products 前缀,可以组成一个蓝图 products
- 相当于四个视图函数,两个蓝图
程序中包含 4 个视图函数,根据页面路径,Flask 将请求转发给对应的视图函数,从浏览器发送过来的请求的处理过程如下图所示
使用蓝图后,路由匹配流程
- 浏览器访问路径 /products/car
- Flask 框架在蓝图 news 和蓝图 products 中查找匹配该页面路径的路由
- 发现在蓝图 products 中,存在和路径 /products/car 匹配的视图函数 car_products
- 最后将请求转发给函数 car_products 处理
实战小栗子
目录结构
例子程序包括 2 个蓝图,由 3 个文件构成:
app.py
,程序的主文件;news.py
,实现蓝图 news;products.py
,实现蓝图 products。
app.py 代码
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/7/12 8:36 下午 # file: app.py """ # 导入 Flask 和 蓝图 Blueprint from flask import Flask, Blueprint # 导入蓝图类 from s7_blueprints import news from s7_blueprints import products app = Flask(__name__) # 注册蓝图 app.register_blueprint(news.blueprint) app.register_blueprint(products.blueprint) if __name__ == '__main__': app.run(debug=True)
news.py 代码
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/7/12 8:36 下午 # file: news.py """ # 导入蓝图 from flask import Blueprint """ 实例化蓝图对象 第一个参数:蓝图名称 第二个参数:导入蓝图的名称 第三个参数:蓝图前缀,该蓝图下的路由规则前缀都需要加上这个 """ blueprint = Blueprint('news', __name__, url_prefix="/news") # 用蓝图注册路由 @blueprint.route("/society/") def society_news(): return "社会新闻板块" @blueprint.route("/tech/") def tech_news(): return "新闻板块"
注意:页面的绝对路径是 /news/society/ 和 /news/tech/,因为蓝图的 url_prefix 设置为 news,在蓝图内部,页面的相对路径是 /society/ 和 /tech/
products.py 代码
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/7/12 8:36 下午 # file: products.py """ from flask import Blueprint blueprint = Blueprint("products", __name__, url_prefix="/product") @blueprint.route("/car") def car_products(): return "汽车产品版块" @blueprint.route("/baby") def baby_products(): return "婴儿产品版块"
注意:页面的绝对路径是 /products/car/ 和 /product/baby/,因为蓝图的 url_prefix 等于 products,在蓝图内部,页面的相对路径是 /car/ 和 /baby/
postman 发起请求的结果