Flask - 蓝图的基本使用
一、前言
参考https://www.cnblogs.com/poloyy/p/15004389.html
- 在前面的例子中,所有的页面处理逻辑都是放在同一个文件中,随着业务代码的增加,将所有代码都放在单个程序文件中是非常不合适的
- 不仅会让阅读代码变得困难,而且会给后期维护带来麻烦
- Flask 中使用蓝图,提供了模块化管理程序路由的功能,使程序结构更加清晰
二、蓝图简介
- 随着 Flask 程序越来越复杂,需要对程序进行模块化的处理
- 蓝图 (Blueprint) 是 Flask 程序的模块化处理机制
- 它是一个存储视图方法的集合
- Flask 程序通过 Blueprint 来组织 URL 以及处理请求
1、 Blueprint 具有以下属性
- 一个项目可以具有多个 Blueprint
- Blueprint 可以单独拥有自己的模板、静态文件的目录
- 在应用初始化时,注册需要使用的 Blueprint
2、基本用法
功能概述:假设网站包含有如下 4 个页面
- 前两个都是 /news 前缀,可以组成一个蓝图 news
- 后两个是 /products 前缀,可以组成一个蓝图 products
- 相当于四个视图函数,两个蓝图
使用蓝图后,路由匹配流程
- 浏览器访问路径 /products/car
- Flask 框架在蓝图 news 和蓝图 products 中查找匹配该页面路径的路由
- 发现在蓝图 products 中,存在和路径 /products/car 匹配的视图函数 car_products
- 最后将请求转发给函数 car_products 处理
三、实战
1、目录结构
例子程序包括 2 个蓝图,由 3 个文件构成:
practice.py
,程序的主文件;news.py
,实现蓝图 news;products.py
,实现蓝图 products。
2、practice.py
from flask import Flask, Blueprint # 导入蓝图类 from blueprints import news,products app = Flask(__name__) # 注册蓝图 app.register_blueprint(news.blueprint) app.register_blueprint(products.blueprint) if __name__ == '__main__': app.run(debug=True)
3、news.py
页面的绝对路径是 /news/society/ 和 /news/tech/,因为蓝图的 url_prefix 设置为 news,在蓝图内部,页面的相对路径是 /society/ 和 /tech/
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 "新闻版块"
4、products.py
页面的绝对路径是 /products/car/ 和 /product/baby/,因为蓝图的 url_prefix 等于 products,在蓝图内部,页面的相对路径是 /car/ 和 /baby/
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 "婴儿产品版块"
5、请求结果
四、更具扩展性的架构
概述
随着业务代码的增加,需要为 Flask 程序提供一个具备扩展性的架构,根据 Flask 程序的扩展性分为如下三种类型:
1、所有的页面逻辑放在同一个文件中
在这种架构中,程序完全不具备扩展性
在初学 Flask 时,使用的栗子都是这种类型
2、使用一个独立的 Python 文件实现蓝图
在这种架构中,程序具备一定的扩展性:
- 程序由主程序和多个蓝图构成
- 每个蓝图对应一个 Python 文件
- 所有的蓝图共享相同的模板文件目录
- 所有的蓝图共享相同的静态文件目录
上面的栗子就是采用这种架构
程序包含 2 个蓝图: news 和 products,由 3 个文件构成:practice.py
、news.py
、products.py
,其中 news.py
实现新闻版块,products.py
实现产品版块
3、使用一个独立的目录实现蓝图
在这种架构中,程序的扩展性最好:
- 程序由主程序和多个蓝图构成
- 每个蓝图对应一个独立的目录,存储与这个蓝图相关的文件
- 每个蓝图有一个独立的模板文件目录
- 每个蓝图有一个独立的静态文件目录
模板文件寻找规则
每个蓝图可以拥有独立的模板文件目录,模板文件寻找规则如下:
- 如果项目中的 templates 文件夹中存在相应的模板文件,则使用 templates 文件夹下的模板文件;
- 如果项目中的 templates 文件夹中没有相应的模板文件,则使用定义蓝图的时候指定的 templates 文件夹下的模板文件
- 项目中的 templates 文件夹优先级大于指定的 templates 文件夹
静态文件寻找规则
每个蓝图可以独立的静态文件目录,静态文件寻找规则如下:
- 如果项目中的 static 文件夹中存在相应的静态文件,则使用 static 文件夹下的静态文件
- 如果项目中的 static 文件夹中没有相应的静态文件,则使用定义蓝图的时候指定的 static 文件夹下的静态文件
- 项目中的 templates 文件夹优先级大于指定的 templates 文件夹
五、扩展性实战例子
1、目录结构
2、目录功能描述
3、 文件功能描述
4、app.py
from flask import Flask import news,products app = Flask(__name__) app.register_blueprint(news.blueprint) app.register_blueprint(products.blueprint) app.run(debug=True)
5、news/__init.py__
- 蓝图中页面的 URL 前缀为 /news;
- 蓝图的模板目录为 templates,绝对路径为 ‘项目目录 /news/templates’;
- 蓝图的静态文件目录为 static,绝对路径为 ‘项目目录 /news/static’
- 调用 render_template (‘society.html’) 渲染模板文件 society.html,根据模板文件的查找规则,最终在 ‘项目目录 /news/templates’ 目录下找到模板文件
# 导入蓝图 from flask import Blueprint, render_template """ 实例化蓝图对象 第一个参数:蓝图名称 第二个参数:导入蓝图的名称 第三个参数:蓝图前缀,该蓝图下的路由规则前缀都需要加上这个 """ blueprint = Blueprint('news', __name__, url_prefix="/news", template_folder="templates", static_folder="static") # 用蓝图注册路由 @blueprint.route("/society/") def society_news(): return render_template('society.html') @blueprint.route("/tech/") def tech_news(): return "IT 新闻板块"
6、news/templates/society.html
在模板文件中引用了静态文件 news.css。{{url_for (‘news.static’,filename=‘news.css’) }} 的输出为 news/static/news.css,其中 news.static 表示蓝图 news 的 static 目录
<link rel="stylesheet" href="{{ url_for('news.static',filename='news.css')}}"> <h1>社会新闻</h1>
7、news/static/news.css
h1 { color: red; }
8、product.py/__init.py__
from flask import Blueprint blueprint = Blueprint('products', __name__, url_prefix='/products') @blueprint.route("/car") def car_products(): return "汽车产品版块" @blueprint.route("/baby") def baby_products(): return "婴儿产品版块"
9、浏览器访问效果
我的编辑好像没升级,不支持部分css,本来社会新闻的标题应当是红色的
10、注意
- 根据 templates、static 的查找规则,会优先查找项目根目录的 templates、static 目录下是否有对应的模板文件、静态文件
- 这里 society.html 同时出现在根目录的 templates 和蓝图目录的 templates,应该优先返回根目录的 templates 下的 society.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?