前言

  • 在前面的例子中,所有的页面处理逻辑都是放在同一个文件中,随着业务代码的增加,将所有代码都放在单个程序文件中是非常不合适的
  • 不仅会让阅读代码变得困难,而且会给后期维护带来麻烦
  • 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 将请求转发给对应的视图函数,从浏览器发送过来的请求的处理过程如下图所示

使用蓝图后,路由匹配流程

  1. 浏览器访问路径 /products/car
  2. Flask 框架在蓝图 news 和蓝图 products 中查找匹配该页面路径的路由
  3. 发现在蓝图 products 中,存在和路径 /products/car 匹配的视图函数 car_products
  4. 最后将请求转发给函数 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.pynews.pyproducts.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)- 蓝图的基本使用的更多相关文章

  1. Flask - Flask的蓝图(BluePrint)

    目录 Flask - Flask的蓝图(BluePrint) 一. 初始Flask蓝图 进阶Flask蓝图 使用蓝图做一个增删改查 1.使用蓝图进行web应用搭建: 2.使用Flask蓝图,查看学生信 ...

  2. Python Flask Blueprint 蓝图

    Python Flask Blueprint 蓝图 本篇来了解一下 Flask 中 Blueprint 蓝图,什么蓝图 ..就是一个分模块的扩展而已,用来让不同的 业务模块api 分到不同的pytho ...

  3. python flask框架 蓝图的使用

    蓝图的目的是实现 各个模块的视图函数写在不同的py文件当中. 主视图 中 导入 分路由视图的模块,并且注册蓝图对象 分路由视图中 利用 蓝图对象 的route 进行装饰视图函数 主路由视图函数: #c ...

  4. Flask的蓝图和红图

    1.蓝图 对于简单的项目来说,比如项目就只有一个user模块,我们可以都将视图函数定义在一个文件里面,不需要用到蓝图. 但是如果我们的项目有多个模块,如下有v1模块,v2模块.....等,那么如果我们 ...

  5. flask Blueprint蓝图

    首先要了解蓝图的作用,模拟场景在团队开发过程中团队每个人都在写自己负责的功能模块,那多个py文件模板,我们如果完成后需要运行是不是要运行多个服务?但是我们的项目是一个整体,而不是零散的,所以我们怎么把 ...

  6. flask框架----蓝图

    蓝图(flask中多py文件拆分都要用到蓝图) 如果代码非常多,要进行归类.不同的功能放在不同的文件,吧相关的视图函数也放进去.蓝图也就是对flask的目录结构进行分配(应用于小,中型的程序), 小中 ...

  7. flask使用蓝图,创建副本

    随着flask的发展,flask框架越来越复杂,我们需要进行模块化处理,因为之前学过python模块化管理,我可以对一个flask程序进行简单的模块化处理. 我们都有一个博客程序,由此可知博客的前端界 ...

  8. flask session,蓝图,装饰器,路由和对象配置

    1.Flask 中的路由   *endpoint - url_for 反向地址  *endpoint 默认是视图函数名  *methods 指定视图函数的请求方式,默认GET  defaults={& ...

  9. Flask之蓝图的使用

    蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? 比如说,你有一个客户管理系统,最开始的时候,只有一个查看 ...

  10. Flask 中蓝图的两种表现形式

    最近在学Flask,特有的@X.route 很适合RESTfuld API, 一般小型应用,在一个py文件中就可以完成,但是维护起来比较麻烦. 想体验Django那样的MVT模式, 看到 Flask提 ...

随机推荐

  1. 友盟+U-APM应用性能报告:Android崩溃率达0.32%,OPPO 、华为、VIVO 崩溃表现良好

    ​随着信息技术高速发展,移动互联几乎已成为了一种生活方式的代名词,在全民上网的数字热潮中,如何能最大程度保障产品服务的稳定性,提供良好的用户体验,是当前企业都需要思考和亟待解决的问题.App的应用性能 ...

  2. 高德Serverless平台建设及实践

    导读 高德启动Serverless建设已经有段时间了,目前高德Serverless业务的峰值早已超过十万QPS量级,平台从0到1,QPS从零到超过十万,成为阿里集团内Serverless应用落地规模最 ...

  3. linux免密传输文件 nc

    nc命令很强大,用来在内网传输小文件也不错,最主要的是仅一次传输的情况下不需要用户和密码即可直接接受与发送文件 不管是linux2linux 还是 linux2windows皆可 先决条件: 1.使用 ...

  4. 第6讲 | 交换机与VLAN:办公室太复杂,我要回学校

    第6讲 | 交换机与VLAN:办公室太复杂,我要回学校 拓扑结构是怎么形成的? 一个交换机肯定不够用,需要多台交换机,交换机之间连接起来,就形成一个稍微复杂的拓扑结构. 如何解决常见的环路问题? 包转 ...

  5. VMware ESXi 7.0 U2 SLIC & Unlocker Intel NUC 专用镜像

    构建 Nano Datacenter 的两大平台 在测试环境或者家庭实验室(Home lab)中使用 VMware vSphere 作为虚拟化平台非常普遍,笔者更倾向使用 Nano Datacente ...

  6. Auto ML自动调参

    Auto ML自动调参 本文介绍Auto ML自动调参的算法介绍及操作流程. 操作步骤 登录PAI控制台. 单击左侧导航栏的实验并选择某个实验. 本文以雾霾天气预测实验为例. 在实验画布区,单击左上角 ...

  7. Django(53)二次封装Response

    前言 有时候我们使用drf的Response,会发现默认返回的格式不太友好,每次我们都需要写入以下的格式 return Response({ "status": 0, " ...

  8. 面试一次问一次,HashMap是该拿下了(一)

    文章目录 前言 一.HashMap类图 二.源码剖析 1. HashMap(jdk1.7版本) - 此篇详解 2. HashMap(jdk1.8版本) 3. ConcurrentHashMap ~~ ...

  9. 狂神说Linux笔记:Vim和账号、用户组、磁盘管理

    什么是Vim编辑器 Vim是从 vi 发展出来的一个文本编辑器.代码补完.编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用. 简单的来说, vi 是老式的字处理器,不过功能已经很齐全了,但 ...

  10. Pytorch CNN网络MNIST数字识别 [超详细记录] 学习笔记(三)

    目录 1. 准备数据集 1.1 MNIST数据集获取: 1.2 程序部分 2. 设计网络结构 2.1 网络设计 2.2 程序部分 3. 迭代训练 4. 测试集预测部分 5. 全部代码 1. 准备数据集 ...