Flask使用蓝图和注意事项

Flask使用蓝图的概念  来制作应用程序组件 和 支持应用程序内部 或 跨应用程序的通用模式
蓝图可以大大简化大型应用程序的工作方式,并为Falsk扩展提供了在应用程序上注册操作的中心手段。
Blueprint对象的工作方式于Falsk应用程序对象类似,但实际上它不是一个应用程序。

总之,蓝图可以使我们的程序更加模块化,不同功能的路由可以放在不同的模块下,最后集中到启动类中
蓝图使用起来就像应用中的子应用一样,可以有自己的模板,静态目录,有自己的视图函数和URL规则
蓝图之间互相不影响,但是它们又属于应用中,可以共享应用中的配置,对于大型应用来说,我们可以通过添加
蓝图来拓展应用功能,而不至于影响原来的程序,不过需要注意的是,目前Flask蓝图的注册时静态的,不支持可插拔
(比较好的习惯是将蓝图放在一个单独的文件包中,虽然多个蓝图可以共存同一个文件夹下,但是最好不要这样做。)

下面是我的项目文件目录,注册了蓝图admin和home

蓝图的注册

在运行文件app.py中加入  app.register_blueprint(admin, url_prefix="/admin") admin是创建的蓝图对象

这里我在admin下的admin_module.py中创建蓝图,

from flask import Blueprint, render_template
admin = Blueprint("admin", __name__, template_folder="templates", static_folder="static")
"""
    这里将演示Flask中蓝图的使用,在项目下创建了一个admin包,在当前文件下来编写蓝图
    我们创建了蓝图对象"admin_db",它使用起来和Flask应用的app对象类似,它有自己的路由"admin_db.route()"
    初始化Blueprint对象的第一个参数"admin"指定了这个蓝图的名称,第二个参数指定了蓝图所在的模块名
    这里再稍微说下python中的特殊属性 __name__ 当用在一个文件里时,代表的是模块(或包)的名字
    
    我们可以指定蓝图自己的模板目录和静态目录,比如我们创建蓝图时传入:
    admin_db = Blueprint("admin", __name__, template_folder="templates", static_folder="static")
"""


# 这里这个defaults对应/<a>这个值,如果后面有输入变量,则默认为小白
@admin.route("/<a>", defaults={"a": "小白"})
def index(a):
    return render_template("admin/index.html", data=a)


@admin.route("/")
def test():
    return render_template("admin/index.html")

同时我又在pro文件夹下又注册了蓝图home,对应的home_module.py代码如下

from flask import Blueprint, render_template
# template_folder="templates", static_folder="static", 这里没有指定的templates的话默认也是这两个值,
# 但是如果在这个蓝图前面也有蓝图是这样写的话,当前蓝图可以会到前面蓝图中的templates中查找同名html,
# 所以官方建议按照 home/templates/home/***.html的目录结构建立模板,这样的话蓝图查找模板内容就不会出错了
home_db = Blueprint("home", __name__, url_prefix="/home")


@home_db.route("/")
def index():
    return render_template("index.html")

蓝图资源

这里需要注意的是,我在admin中把html模板放在了 templates/admin/index.html 这样的目录下,这样是为了区分蓝图home和admin的模板,官方的建议是按照 admin/templates/admin/***.html 这样的方式存放模板(官方文档

如果admin的模板路径和home的模板路径一样都为  templates/***.html这样的格式的话,在我调用http://127.0.0.1:5000/admin/

显示的是蓝图admin下templates中的index.html没有错,但是如果后面我调用http://127.0.0.1:5000/home/所显示出来的index.html页面还是admin中的index.html页面,问题就展示出来了,如果有两个蓝图或多个蓝图,它们的模板目录都为  ***/templates/***.html这样的结构,如果在它们的templates下有着同名html文件,那么后面的蓝图加载的同名html文件会是第一个蓝图中的html

蓝图构建URL

使用url_for(),第一个参数我们称为端点,例如我们在该项目中创建的蓝图名 "admin",创建Blueprint对象时的第一个参数
所以我们通过端点名称来获取URL时,我们可以这样写:
form flask import url_for
url_for("admin.index")      # return /admin/
url_for("admin.static",filename="style.css")    # return /admin/static/style.css
这样才能获得"admin"蓝图下视图或资源的URL地址,如果"url_for()"函数的调用就在本蓝图下,
那么蓝图名就可以省略,但是必须留下"."表示当前蓝图:
url_for(".index")  url_for(".static",filename="style.css")

例如admin下的测试HTML index中的js由下列代码所示加载

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--这里给蓝图加载js,前加上admin-->
    <script type="text/javascript" src="{{ url_for("admin.static",filename="js/jquery-1.8.3.min.js") }}"></script>
</head>
<body>
<h1>这是一个测试{{ data }},来自admin</h1>
</body>
</html>

当然也可以使用相对路径的方式加载: ../pro/admin/static/js/jquery-1.8.3.min.js

如果项目不大的话可以不使用的蓝图的方式,一开始接触的时候,看到别人的文件目录都是把templates文件夹放到和运行文件不同级的目录下,最开始我也按照那种方式创建文件目录,当时我并没有注册蓝图,所以在app.py中的视图函数一直找不到templates下的html文件,直到创建蓝图后才发现,app.py中视图函数没有找到html的话,会到蓝图下的templates中去找同名的html文件,

例如我的app.py中 

from flask import Flask, render_template
from pro.admin.admin_module import admin
from pro.home.home_module import home_db

app = Flask(__name__, template_folder="template")

app.register_blueprint(admin, url_prefix="/admin")   # url_prefix="/admin" 指定蓝图的URL前缀
app.register_blueprint(home_db)     # 这里没有指定URL前缀是因为在创建蓝图时就设置好了


@app.route('/<name>')
def hello_world(name):
    return render_template("app.html", data=name)

上面代码中,我建立Flask对象时,指定的template_folder="template" ,如下图所示,所以app.py中的视图函数会到同级目录中的template中去找对应的html, 如果没有指定template_folder,且没有在同级目录中创建templates文件夹,那么app.py的视图函数会到蓝图下的templates中去找相同名字的html

学习笔记仅供参考,

参考:http://www.bjhee.com/flask-ad6.html

官方文档:http://docs.jinkan.org/docs/flask/blueprints.html

猜你喜欢

转载自blog.csdn.net/rongDang/article/details/81164052