前言

  • 在前面的例子中,所有的页面处理逻辑都是放在同一个文件中,随着业务代码的增加,将所有代码都放在单个程序文件中是非常不合适的
  • 不仅会让阅读代码变得困难,而且会给后期维护带来麻烦
  • 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. maven工具使用json-lib时,JSONArray.fromObject()不能执行的解决方案

    前端代码我就不展示了 ,下面说明下我遇到问题的情况,如果不想看可以直接划到黄色字体部分直接找解决方法哦~~(相关jar包我会放在云中,想要的自己下载哦,链接在视频最下面!!) 我的pom文件,如下,导 ...

  2. 【Microstation】三维建模基础及软件入门到精通实验教程目录

    @ 目录 1. 专栏简介 2. 专栏地址 3. 专栏目录 1. 专栏简介 MicroStation是一款非常不错的二维和三维设计软件,由奔特力(Bentley)工程软件系统有限公司开发的一款软件.在C ...

  3. untiy项目中使用MD5加密

    没有详细研究过暂时贴上代码以便以后研究: public static string MD5Encrypt(string strText) { MD5 md5 = MD5.Create(); byte[ ...

  4. 第13讲 | 套接字Socket:Talk is cheap, show me the code

    第13讲 | 套接字Socket:Talk is cheap, show me the code 基于 TCP 和 UDP 协议的 Socket 编程.在讲 TCP 和 UDP 协议的时候,我们分客户 ...

  5. opencv——自适应阈值Canny边缘检测

    前言 Canny边缘检测速度很快,OpenCV中经常会用到Canny边缘检测,以前的Demo中使用Canny边缘检测都是自己手动修改高低阈值参数,最近正好要研究点小东西时,就想能不能做个自适应的阈值, ...

  6. NGINX缓存使用官方指南

    我们都知道,应用程序和网站一样,其性能关乎生存.但如何使你的应用程序或者网站性能更好,并没有一个明确的答案.代码质量和架构是其中的一个原因,但是在很多例子中我们看到,你可以通过关注一些十分基础的应用内 ...

  7. 在Visual Studio 中使用git——分支管理-下(九)

    在Visual Studio 中使用git--什么是Git(一) 在Visual Studio 中使用git--给Visual Studio安装 git插件(二) 在Visual Studio 中使用 ...

  8. Mobileye高级驾驶辅助系统(ADAS)

    Mobileye高级驾驶辅助系统(ADAS) Mobileye is the global leader in the development of vision technology for Adv ...

  9. YOLOv4没交棒,但YOLOv5来了!

    YOLOv4没交棒,但YOLOv5来了! 前言 4月24日,YOLOv4来了! 5月30日,"YOLOv5"来了! 这里的 "YOLOv5" 是带有引号的,因为 ...

  10. go 技巧: 实现一个无限 buffer 的 channel

    前言 总所周知,go 里面只有两种 channel,一种是 unbuffered channel, 其声明方式为 ch := make(chan interface{}) 另一种是 buffered ...