Flask 使用了 蓝图 的概念在一个应用或者跨应用中构建应用组件以及支持通用模式。 蓝图很好地简化了大型应用工做的方式,并提供给 Flask 扩展在应用上注册操做的核心方法。 一个 Blueprint
对象与 Flask
应用对象的工做方式很像,但它确实不是一个应用, 而是一个描述如何构建或扩展应用的 蓝图 。css
Flask中的蓝图旨在针对这些状况:html
Flask 中的蓝图不是即插应用,由于它实际上并非一个应用 – 它是能够注册,甚至能够屡次注册到应用上的操做集合。为何不使用多个应用对象?你能够作到那样 (见 应用调度 ),可是你的应用会有分开的配置,并在 WSGI 层管理。python
蓝图做为 Flask 层提供分割的替代,共享应用配置,而且能够更改所注册的应用对象。其短板是你不能在应用建立后撤销注册一个蓝图而不销毁整个应用对象。web
蓝图的基本设想是它们记录注册到一个应用时的操做执行状况。 当从一个端点到另外一端分发请求和生成 URL 时,Flask 关联视图函数和蓝图。flask
这看起来像是一个很是基本的蓝图。在这个案例中,咱们想要实现一个简单渲染静态模板的蓝图:app
from flask import Blueprint, render_template, abort from jinja2 import TemplateNotFound simple_page = Blueprint('simple_page', __name__, template_folder='templates') @simple_page.route('/', defaults={'page': 'index'}) @simple_page.route('/<page>') def show(page): try: return render_template('pages/%s.html' % page) except TemplateNotFound: abort(404)
当咱们使用 \@simple_page.route
装饰器绑定函数时,蓝图会记录下所登记的 show 函数。当之后在应用中注册蓝图时,这个函数会被注册到应用中。此外,它会给函数名加上由 Blueprint
的构造函数中给出的蓝图的名称做为前缀 (在此例中是 simple_page
)。函数
如何注册蓝图了?像这样:url
from flask import Flask from yourapplication.simple_page import simple_page app = Flask(__name__) app.register_blueprint(simple_page)
若是你检查注册到应用的规则,你将会发现这些:spa
[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
<Rule '/<page>' (HEAD, OPTIONS, GET) -> simple_page.show>,
<Rule '/' (HEAD, OPTIONS, GET) -> simple_page.show>]
第一个显然是来自应用自身,用于静态文件。其它的两个用于 simple_page
蓝图中的 show 函数。如你所见,它们的前缀是蓝图的名称,而且用一个点(.
)来分割。code
不过,蓝图也能够在不一样的位置挂载:
app.register_blueprint(simple_page, url_prefix='/pages')
果真,生成这些规则:
[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
<Rule '/pages/<page>' (HEAD, OPTIONS, GET) -> simple_page.show>,
<Rule '/pages/' (HEAD, OPTIONS, GET) -> simple_page.show>]
总之,你能够屡次注册蓝图,可是不必定每一个蓝图都能正确响应。 是否可以屡次注册实际上取决于你的蓝图是如何编写的,是否能根据不一样的位置作出正确的响应。
蓝图也能够提供资源。有时候你会只为它提供的资源而引入一个蓝图。
与常规应用同样,蓝图被认为是包含在一个文件夹中。虽然多个蓝图能够源自相同的文件夹中, 它并没必要须是这种状况而且一般不建议这样作。
这个文件夹会从 Blueprint
的第二个参数中推断出来,一般是 __name__ 。 这个参数决定对应蓝图的是哪一个逻辑的 Python 模块或包。若是它指向一个存在的 Python 包,这个包(一般是文件系统中的文件夹)就是资源文件夹。若是是一个模块, 模块所在的包就是资源文件夹。你能够访问 Blueprint.root_path
属性来查看资源文件夹什么:
>>> simple_page.root_path '/Users/username/TestProject/yourapplication'
你能够使用 open_resource()
函数快速性这个文件夹中打开资源:
with simple_page.open_resource('static/style.css') as f: code = f.read()
一个蓝图能够经过 static_folder 关键字参数提供一个指向文件系统上文件夹的路 径,来公开一个带有静态文件的文件夹。这能够是一个绝对路径,也能够是相对于蓝图文件夹的路径:
admin = Blueprint('admin', __name__, static_folder='static')
默认状况下,路径最右边的部分就是它在 web 上所公开的地址。由于这里这个文件夹叫作 static
, 它会在蓝图 + /static
的位置上可用。也就是说,蓝图为 /admin
把静态文件夹注册到 /admin/static
。
最后是命名的 blueprint_name.static ,这样你能够生成它的 URL ,就像你对应用的静态文件夹所作的那样:
url_for('admin.static', filename='style.css')
若是你想要蓝图公开模板,你能够提供 Blueprint
构造函数中的 template_folder 参数来实现:
admin = Blueprint('admin', __name__, template_folder='templates')
像对待静态文件同样,路径能够是绝对的或是相对蓝图资源文件夹的。模板文件夹会 被加入到模板的搜索路径中,可是比实际的应用模板文件夹优先级低。 这样,你能够容易地在实际的应用中覆盖蓝图提供的模板。
那么当你有一个 yourapplication/admin
文件夹中的蓝图而且你想要渲染 'admin/index.html'
模板, 且你已经提供了 templates
做为 template_folder ,你须要这样建立文件: yourapplication/admin/templates/admin/index.html
。
当你想要从一个页面连接到另外一个页面,你能够像一般一个样使用 url_for()
函数,只是你要在 URL 的末端加上蓝图的名称和一个点(.
)做为前缀:
url_for('admin.index')
此外,若是你在一个蓝图的视图函数或是模板中想要从连接到同一蓝图下另外一个端点, 你能够经过对端点的只加上一个点做为前缀来使用相对的重定向:
url_for('.index')
这个案例中,它实际上连接到 admin.index
,假如请求被分派到任何其它的 admin 蓝图端点。