New in version 0.7.
為了在一個或多個應用中,使應用模塊化并且支持常用方案, Flask 引入了 藍圖 概念。藍圖可以極大地簡化大型應用并為擴展提供集中的注冊入口。
Blueprint 對象與 Flask 應用對象的工作方式類似,但不是一個真正 的應用。它更像一個用于構建和擴展應用的 藍圖 。
Flask 中藍圖有以下用途:
Flask 中的藍圖不是一個可插撥的應用,因為它不是一個真正的應用,而是一套可以注冊 在應用中的操作,并且可以注冊多次。那么為什么不使用多個應用對象呢?可以使用多個 應用對象(參見應用調(diào)度 ),但是這樣會導致每個應用都使用自己獨立的配置,且只能在 WSGI 層中管理應用。
而如果使用藍圖,那么應用會在 Flask 層中進行管理,共享配置,通過注冊按需改變應用 對象。藍圖的缺點是一旦應用被創(chuàng)建后,只有銷毀整個應用對象才能注銷藍圖。
藍圖的基本概念是:在藍圖被注冊到應用之后,所要執(zhí)行的操作的集合。當分配請求時, Flask 會把藍圖和視圖函數(shù)關聯(lián)起來,并生成兩個端點之前的 URL 。
以下是一個最基本的藍圖示例。在這里,我們將使用藍圖來簡單地渲染靜態(tài)模板:
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 裝飾器綁定一個函數(shù)時,藍圖會記錄下所登記的 show 函數(shù)。當以后在應用中注冊藍圖時,這個函數(shù)會被注冊到應用中。另外,它會把 構建 Blueprint 時所使用的名稱(在本例為 simple_page )作為函數(shù)端點 的前綴。
可以這樣注冊藍圖:
from flask import Flask
from yourapplication.simple_page import simple_page
app = Flask(__name__)
app.register_blueprint(simple_page)
以下是注冊藍圖后形成的規(guī)則:
[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
<Rule '/<page>' (HEAD, OPTIONS, GET) -> simple_page.show>,
<Rule '/' (HEAD, OPTIONS, GET) -> simple_page.show>]
第一條很明顯,是來自于應用本身的用于靜態(tài)文件的。后面兩條是用于藍圖 simple_page 的 show 函數(shù)的。你可以看到,它們的前綴都是藍圖的名稱,并且使用一個點( . )來分隔。
藍圖還可以掛接到不同的位置:
app.register_blueprint(simple_page, url_prefix='/pages')
這樣就會形成如下規(guī)則:
[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
<Rule '/pages/<page>' (HEAD, OPTIONS, GET) -> simple_page.show>,
<Rule '/pages/' (HEAD, OPTIONS, GET) -> simple_page.show>]
總之,你可以多次注冊藍圖,但是不一定每個藍圖都能正確響應。是否能夠多次注冊實際 上取決于你的藍圖是如何編寫的,是否能根據(jù)不同的位置做出正確的響應。
藍圖還可以用于提供資源。有時候,我們僅僅是為了使用一些資源而使用藍圖。
和普通應用一樣,藍圖一般都放在一個文件夾中。雖然多個藍圖可以共存于同一個文件夾中,但是最好不要這樣做。
文件夾由 Blueprint 的第二個參數(shù)指定,通常為 __name__
。這個參數(shù)指定與藍圖相關的邏輯 Python 模塊或包。如果這個參數(shù)指向的是實際的 Python 包(文件 系統(tǒng)中的一個文件夾),那么它就是資源文件夾。如果是一個模塊,那么這個模塊包含的 包就是資源文件夾。可以通過 Blueprint.root_path 屬性來查看藍圖的資源文件夾:
>>> simple_page.root_path
'/Users/username/TestProject/yourapplication'
可以使用 open_resource() 函數(shù)快速打開這個文件夾中的資源:
with simple_page.open_resource('static/style.css') as f:
code = f.read()
藍圖的第三個參數(shù)是 static_folder 。這個參數(shù)用以指定藍圖的靜態(tài)文件所在的文件夾,它可以是一個絕對路徑也可以是相對路徑。:
admin = Blueprint('admin', __name__, static_folder='static')
缺省情況下,路徑最右端的部分是在 URL 中暴露的部分。上例中的文件夾為 static ,那么 URL 應該是藍圖加上 /static
。藍圖注冊為 /admin
,那么 靜態(tài)文件夾就是 /admin/static
。
端點的名稱是 blueprint_name.static
,因此你可以使用和應用中的文件夾一樣的方法 來生成其 URL:
url_for('admin.static', filename='style.css')
如果你想使用藍圖來暴露模板,那么可以使用 Blueprint 的 template_folder 參數(shù):
admin = Blueprint('admin', __name__, template_folder='templates')
和靜態(tài)文件一樣,指向藍圖資源文件夾的路徑可以是絕對的也可以是相對的。藍圖中的 模板文件夾會被添加到模板搜索路徑中,但其優(yōu)先級低于實際應用的模板文件夾。這樣在 實際應用中可以方便地重載藍圖提供的模板。
假設你的藍圖便于 yourapplication/admin 中,要渲染的模板是 'admin/index.html' , template_folder 參數(shù)值為 templates ,那么真正的 模板文件為: yourapplication/admin/templates/admin/index.html
。
如果要創(chuàng)建頁面鏈接,可以和通常一樣使用 url_for() 函數(shù),只是要把藍圖名稱作為端點的前綴,并且用一個點( . )來 分隔:
url_for('admin.index')
另外,如果在一個藍圖的視圖函數(shù)或者被渲染的模板中需要鏈接同一個藍圖中的其他端點,那么使用相對重定向,只使用一個點使用為前綴:
url_for('.index')
如果當前請求被分配到 admin 藍圖端點時,上例會鏈接到 admin.index 。
? Copyright 2013, Armin Ronacher. Created using Sphinx.