解釋1:
允許將應用組織為模塊,每個模塊有自洽的 MVC,開發(fā)者做些工作可以使模塊間依賴盡可能少,必要時可以按 blueprint 為單位做垂直拆分。
依賴反轉,允許把 route 掛到 blueprint 對象而非全局 app 對象上。
解釋2:
1 概述
藍圖/Blueprint是Flask應用程序組件化的方法,可以在一個應用內或跨越 多個項目共用藍圖。使用藍圖可以極大地簡化大型應用的開發(fā)難度,也為Flask擴展 提供了一種在應用中注冊服務的集中式機制。
2 初識藍圖
藍圖/Blueprint對象用起來和一個應用/Flask對象差不多,最大的區(qū)別在于一個 藍圖對象沒有辦法獨立運行,必須將它注冊到一個應用對象上才能生效。
使用藍圖可以分為三個步驟
1.創(chuàng)建一個藍圖對象
ezbp =Blueprint("ezbp",__name__)
2.在這個藍圖對象上進行操作,入注冊路由、指定靜態(tài)文件夾、注冊模板過濾器...
@ezbp.route('/')defezbp_index():return'Welcome to my blueprint'
3.在應用對象上注冊這個藍圖對象
app.register_blueprint(ezbp,url_prefix='/ezbp')
當這個應用啟動后,通過/ezbp/可以訪問到藍圖中定義的視圖函數(shù)。
考察上面的代碼,可以看到在藍圖對象上注冊路由的方法和在應用對象上完全 一樣,那么,值得思考的是,藍圖和應用對象的運行機制是一樣的嗎?
example:

#-*- coding:utf-8 -*-fromflaskimportFlask,Blueprintapp= Flask(__name__)
@app.route('/')defapp_index():return'go blueprint'ezbp = Blueprint("ezbp",__name__)
@ezbp.route('/')defezbp_index():return'Welcome to my blueprint'app.register_blueprint(ezbp,url_prefix='/ezbp')
app.run(host='0.0.0.0',port=80)

ouptut:


3?運行機制———說白了就是會自動補充URL前綴,并且能使用相同的視圖函數(shù)
藍圖并不是一個可插拔的應用 —— 它只是保存了一組將來可以在應用對象上執(zhí)行 的操作—— 注冊路由就是一種操作。
當在應用對象上調用route 裝飾器或使用add_url_rule()方法注冊路由時, 我們已經知道,這個操作將修改應用對象的兩張路由表:url_map和view_functions; 然而,藍圖對象根本就沒有路由表,當我們在藍圖對象上調用route裝飾器或使用?add_url_rule()方法注冊路由時,它只是在內部的一個延遲操作記錄列表defered_functions中添加了一項:下圖為blueprint和FLask route的對比

lambad s: s.add_url_rule('/',view_func=ezbp_index)定義了一個匿名函數(shù), 參數(shù)s就是將來被傳入的應用對象。當執(zhí)行應用對象的register_blueprint()方法時,應用對象將從藍圖對象的defered_functions列表中取出每一項,并以自身 作為參數(shù)執(zhí)行該匿名函數(shù) —— 即調用應用對象的add_url_rule()方法,這將真正的 修改應用對象的兩張路由表。
所以說,藍圖這個名字起得的確恰當,藍圖的那些方法僅僅記錄了未來應該發(fā)生的操作, 而不是當即實現(xiàn)。
2 藍圖的URL前綴
繼續(xù)使用前一節(jié)的圖,注意其中被橘黃色熒光筆涂抹的代碼:
當我們在應用對象上注冊一個藍圖時,需要指定一個url_prefix關鍵字 參數(shù)(這個參數(shù)默認是/)。在上面的圖中可以看到,在應用最終的路由表url_map中,在藍圖上注冊的路由URL自動被加上了這個前綴。
這相當有用,我們可以在多個藍圖中使用相同的URL規(guī)則而不會最終引起沖突,只要在 注冊藍圖時將不同的藍圖掛接到不同的自路徑即可 —— 想一想對于大型應用而言,不同 的藍圖通常是不同的人員開發(fā)的,你很難保證URL規(guī)則不發(fā)生沖突!
example:

#-*- coding:utf-8 -*-fromflaskimportFlask,Blueprint
shop= Blueprint('shop','shop')
@shop.route('/')defv_index():return'shop root'vip= Blueprint('vip','vip')
@vip.route('/')defv_index():return'vip homepage'admin= Blueprint('admin','admin')
@admin.route('/')defv_index():return'admin root'app= Flask(__name__)
app.register_blueprint(shop,url_prefix='/')
app.register_blueprint(admin,url_prefix='/admin')
app.register_blueprint(vip,url_prefix='/vip')
app.run(host='0.0.0.0',port=80)

output:

4?藍圖的endpoint———加上藍圖前綴
圖繼續(xù),這次關注綠色熒光筆涂抹的代碼:

我們創(chuàng)建藍圖對象時,第一個參數(shù)指定了藍圖的名字。當在應用中注冊藍圖時, 藍圖的路由項中的訪問點endpoint被自動添加了這個名字。
這有什么用?這涉及到url_for()的正確工作與否。
當不同的團隊開發(fā)不同的藍圖時,和URL規(guī)則類似,你很難保證他們的視圖函數(shù)名 彼此不同,尤其像index這樣俗套的名字。如果不對來自不同藍圖的endpoint 進行區(qū)隔,那么url_for('index')到底應該生成那個URL?這顯然無法確定。
一旦給不同藍圖的endpoint加上了藍圖名前綴,我們可以確切地告訴url_for()?了:
url_for('shop.v_index')#/shop/url_for('admin.v_index')#/admin/
example:

#-*- coding:utf-8 -*-fromflaskimportFlask,Blueprint,url_for,render_template_string
shop= Blueprint('shop',__name__)
@shop.route('/')defv_index():return'''
@admin.route('/')defv_index():return'''
app.register_blueprint(shop,url_prefix='/shop')
app.register_blueprint(admin,url_prefix='/admin')
@app.route('/')defv_index():
tpl='''
'''returnrender_template_string(tpl)
app.run(host='0.0.0.0',port=80)

ouput:


5?注冊靜態(tài)目錄路由
和應用對象不同,藍圖對象創(chuàng)建時不會默認注冊靜態(tài)目錄的路由。需要我們在 創(chuàng)建時指定static_folder參數(shù)。
下面的示例將藍圖所在目錄下的ezstatic目錄設置為靜態(tài)目錄:
admin = Blueprint("admin",__name__,static_folder='ezstatic')
app.register_blueprint(admin,url_prefix='/admin')
默認情況下Flask使用文件夾的名稱注冊靜態(tài)文件夾的路由:
+------------------------------------------------------------------+
|? url? ? ? ? ? ? | endpoint? ? ? ? | view_function? ? ? ? ? ? ? |
+------------------------------------------------------------------+
|? /admin/ezstatic | admin.static? ? | Blueprint.send_static_file |
+------------------------------------------------------------------+
現(xiàn)在就可以使用/admin/ezstatic/訪問mystatic目錄下的靜態(tài)文件了。
定制靜態(tài)目錄URL規(guī)則?:可以在創(chuàng)建藍圖對象時使用static_url_path來改變靜態(tài) 目錄的路由。下面的示例將為ezstatic文件夾的路由設置為/lib:
admin = Blueprint("admin",__name__,static_folder='ezstatic',static_url_path='/lib')
app.register_blueprint(admin,url_prefix='/admin')
這時的路由表如下:
+------------------------------------------------------------------+
|? url? ? ? ? ? ? | endpoint? ? ? ? | view_function? ? ? ? ? ? ? |
+------------------------------------------------------------------+
|? /admin/lib? ? ? | admin.static? ? | Blueprint.send_static_file |
+------------------------------------------------------------------+
這樣我們可以使用地址/admin/lib/main.css訪問ezstatic目錄下的main.css文件了