Flask(9)- 蓝图的基本使用
前言
- 在前面的例子中,所有的页面处理逻辑都是放在同一个文件中,随着业务代码的增加,将所有代码都放在单个程序文件中是非常不合适的
- 不仅会让阅读代码变得困难,而且会给后期维护带来麻烦
- 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 发起请求的结果
更具扩展性的架构
概述
随着业务代码的增加,需要为 Flask 程序提供一个具备扩展性的架构,根据 Flask 程序的扩展性分为如下三种类型:
1、所有的页面逻辑放在同一个文件中
在这种架构中,程序完全不具备扩展性
在初学 Flask 时,使用的栗子都是这种类型
2、使用一个独立的 Python 文件实现蓝图
在这种架构中,程序具备一定的扩展性:
- 程序由主程序和多个蓝图构成
- 每个蓝图对应一个 Python 文件
- 所有的蓝图共享相同的模板文件目录
- 所有的蓝图共享相同的静态文件目录
上面的栗子就是采用这种架构
程序包含 2 个蓝图: news 和 products,由 3 个文件构成:app.py
、news.py
、products.py
,其中 news.py
实现新闻版块,products.py
实现产品版块
3、使用一个独立的目录实现蓝图
在这种架构中,程序的扩展性最好:
- 程序由主程序和多个蓝图构成
- 每个蓝图对应一个独立的目录,存储与这个蓝图相关的文件
- 每个蓝图有一个独立的模板文件目录
- 每个蓝图有一个独立的静态文件目录
模板文件寻找规则
每个蓝图可以拥有独立的模板文件目录,模板文件寻找规则如下:
- 如果项目中的 templates 文件夹中存在相应的模板文件,则使用 templates 文件夹下的模板文件;
- 如果项目中的 templates 文件夹中没有相应的模板文件,则使用定义蓝图的时候指定的 templates 文件夹下的模板文件
- 项目中的 templates 文件夹优先级大于指定的 templates 文件夹
静态文件寻找规则
每个蓝图可以独立的静态文件目录,静态文件寻找规则如下:
- 如果项目中的 static 文件夹中存在相应的静态文件,则使用 static 文件夹下的静态文件
- 如果项目中的 static 文件夹中没有相应的静态文件,则使用定义蓝图的时候指定的 static 文件夹下的静态文件
- 项目中的 templates 文件夹优先级大于指定的 templates 文件夹
究极扩展性的栗子
目录结构
目录功能描述
路径 | 功能描述 |
---|---|
templates | 项目默认的模板文件夹 |
static | 项目默认的静态文件夹 |
news | 蓝图 news 的相关文件 |
news/templates | 蓝图 news 的私有模板文件夹 |
news/static | 蓝图 news 的私有静态文件夹 |
products | 蓝图 products 的相关文件 |
products/templates | 蓝图 products 的私有模板文件夹 |
products/static | 蓝图 products 的私有静态文件夹 |
文件功能描述
路径 | 功能描述 |
---|---|
app.py |
主程序 |
news/__init.py__ | 蓝图 news 的实现 |
news/templates/society.html | 属于蓝图 news 的一个模板文件 |
news/static/news.css | 属于蓝图 news 的一个静态文件 |
products/__init.py__ | 蓝图 products 的实现 |
app.py 的代码
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog: https://www.cnblogs.com/poloyy/
# time: 2021/7/12 10:39 下午
# file: 7_blueprint_app.py
""" from flask import Flask from s7_news import news
from s7_product import products app = Flask(__name__) app.register_blueprint(news.blueprint)
app.register_blueprint(products.blueprint) app.run(debug=True)
news/__init.py__ 的代码
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog: https://www.cnblogs.com/poloyy/
# time: 2021/7/12 8:36 下午
""" # 导入蓝图
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 新闻板块"
- 蓝图中页面的 URL 前缀为 /news;
- 蓝图的模板目录为 templates,绝对路径为 ‘项目目录 /news/templates’;
- 蓝图的静态文件目录为 static,绝对路径为 ‘项目目录 /news/static’
- 调用 render_template (‘society.html’) 渲染模板文件 society.html,根据模板文件的查找规则,最终在 ‘项目目录 /news/templates’ 目录下找到模板文件
news/templates/society.html 的代码
<link rel="stylesheet" href="{{ url_for('news.static',filename='news.css')}}">
<h1>社会新闻</h1>
在模板文件中引用了静态文件 news.css。{{url_for (‘news.static’,filename=‘news.css’) }} 的输出为 news/static/news.css,其中 news.static 表示蓝图 news 的 static 目录
news/static/news.css 的代码
h1 {
color: red;
}
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 "婴儿产品版块"
浏览器访问效果
访问 http://localhost:5000/news/society/
验证目录优先级
在根目录下的 templates 目录下也添加一个 society.html 文件,在根目录下的 static 目录下添加一个 project.css
html 代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<link rel="stylesheet" href="{{ url_for('static',filename='project.css') }}">
<h1>社会新闻啊啊啊</h1>
</body>
</html>
css 代码
h1 {
color: blue;
}
预期结果
- 根据 templates、static 的查找规则,会优先查找项目根目录的 templates、static 目录下是否有对应的模板文件、静态文件
- 这里 society.html 同时出现在根目录的 templates 和蓝图目录的 templates,应该优先返回根目录的 templates 下的 society.html
浏览器访问效果
符合预期结果
Blueprint 源码解析
类初始化 __init__ 方法参数列表
- name:蓝图名称,将会被添加到每个 endpoint
- import_name:蓝图包的名称,通常是 __name__,有助于找到 root_path 蓝图
- static_folder:包含静态文件的文件夹,由蓝图的静态路由提供服务,路径以蓝图文件为根路径开始找
- static_url_path:提供静态文件的 url,默认就是 static_folder,如果蓝图没有 url_prefix,应用程序的静态路由将优先,并且蓝图的静态文件将无法访问
- template_folder:包含模板文件的文件夹,路径以蓝图文件为根路径开始找
- url_prefix:会作为蓝图所有路由的前缀路径
- subdomain:蓝图路由将匹配的子域
- url_defaults:蓝图路由的默认值字典
- root_path:默认情况下,蓝图会自动设置这基于“import_name”
Flask(9)- 蓝图的基本使用的更多相关文章
- Flask - Flask的蓝图(BluePrint)
目录 Flask - Flask的蓝图(BluePrint) 一. 初始Flask蓝图 进阶Flask蓝图 使用蓝图做一个增删改查 1.使用蓝图进行web应用搭建: 2.使用Flask蓝图,查看学生信 ...
- Python Flask Blueprint 蓝图
Python Flask Blueprint 蓝图 本篇来了解一下 Flask 中 Blueprint 蓝图,什么蓝图 ..就是一个分模块的扩展而已,用来让不同的 业务模块api 分到不同的pytho ...
- python flask框架 蓝图的使用
蓝图的目的是实现 各个模块的视图函数写在不同的py文件当中. 主视图 中 导入 分路由视图的模块,并且注册蓝图对象 分路由视图中 利用 蓝图对象 的route 进行装饰视图函数 主路由视图函数: #c ...
- Flask的蓝图和红图
1.蓝图 对于简单的项目来说,比如项目就只有一个user模块,我们可以都将视图函数定义在一个文件里面,不需要用到蓝图. 但是如果我们的项目有多个模块,如下有v1模块,v2模块.....等,那么如果我们 ...
- flask Blueprint蓝图
首先要了解蓝图的作用,模拟场景在团队开发过程中团队每个人都在写自己负责的功能模块,那多个py文件模板,我们如果完成后需要运行是不是要运行多个服务?但是我们的项目是一个整体,而不是零散的,所以我们怎么把 ...
- flask框架----蓝图
蓝图(flask中多py文件拆分都要用到蓝图) 如果代码非常多,要进行归类.不同的功能放在不同的文件,吧相关的视图函数也放进去.蓝图也就是对flask的目录结构进行分配(应用于小,中型的程序), 小中 ...
- flask使用蓝图,创建副本
随着flask的发展,flask框架越来越复杂,我们需要进行模块化处理,因为之前学过python模块化管理,我可以对一个flask程序进行简单的模块化处理. 我们都有一个博客程序,由此可知博客的前端界 ...
- flask session,蓝图,装饰器,路由和对象配置
1.Flask 中的路由 *endpoint - url_for 反向地址 *endpoint 默认是视图函数名 *methods 指定视图函数的请求方式,默认GET defaults={& ...
- Flask之蓝图的使用
蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? 比如说,你有一个客户管理系统,最开始的时候,只有一个查看 ...
- Flask 中蓝图的两种表现形式
最近在学Flask,特有的@X.route 很适合RESTfuld API, 一般小型应用,在一个py文件中就可以完成,但是维护起来比较麻烦. 想体验Django那样的MVT模式, 看到 Flask提 ...
随机推荐
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十五)——集中式接口文档实现
之前有小伙伴在评论区留言说如何集成swagger,最开始没有想透给了对方一个似是而非的回答.实际上后来下来想了一下,用.NET5 提供的Source Generator其实可以很方便的实现接口集成.今 ...
- mysql数据库-备份与还原-Percona XtraBackup 2.4备份工具使用
目录 xtrabackup 特点 备份生成的相关文件 xtrabackup 安装 xtrabackup 用法 1 备份 2 预备份 3 还原 4 其他 还原注意事项 xtrabackup实现完全备份及 ...
- IOS 小组件(7):小组件点击交互
引言 前面我们似乎掌握了实现一个小组件所需要的一切技能,默认情况下桌面点击小组件,也正常跳转到了App中.接下来我们一起来看看,小组件是怎么做到点击跳转到App的. 点击交互方式 点击Widget ...
- node.js学习(4)事件
1 导入事件库
- 3D惯导Lidar仿真
3D惯导Lidar仿真 LiDAR-Inertial 3D Plane Simulator 摘要 提出了最*点*面表示的形式化方法,并分析了其在三维室内同步定位与映射中的应用.提出了一个利用最*点*面 ...
- Jmeter(五十一) - 从入门到精通高级篇 - jmeter之运动战(详解教程)
1.简介 运动战是一种军事作战方式,依托较大的作战空间来换取时间移动兵力包围敌方,以优势兵力速战速决,运动战的运用归为这样一段话"避敌主力,诱敌深入,集中优势兵力逐个击破".今天宏 ...
- Spring boot未授权访问造成的数据库外联
一.spring boot 日常测试或攻防演练中像shiro,fastjson等漏洞已经越来越少了,但是随着spring boot框架的广泛使用,spring boot带来的安全问题也越来越多,本文仅 ...
- adb基础命令
adb运行原理: 启动一个 adb 客户端时,此客户端首先检查是否有已运行的 adb 服务器进程.如果没有,它将启动服务器进程.当服务器启动时,它与本地 TCP 端口 5037 绑定,并侦听从 adb ...
- 详细了解 Linkerd 2.10 基础功能,一起步入 Service Mesh 微服务架构时代
Linkerd 提供了许多功能,如:自动 mTLS.自动代理注入.分布式追踪.故障注入.高可用性.HTTP/2 和 gRPC 代理.负载均衡.多集群通信.重试和超时.遥测和监控.流量拆分(金丝雀.蓝/ ...
- Vim一直学不会?试试这个 "真香" 神器
Vim 的使用,一直以来是一个难题 以至于国外的知名程序员问答社区 StackOverFlow 上有一个问题 How to I exit the Vim editor 获得了超过 200万次的浏览量 ...