### 導航
- [索引](# "總目錄")
- [下一頁](# "Flask 擴展") |
- [上一頁](# "請求上下文") |
- [Flask 0.10.1 文檔](#) ?
# 用藍圖實現模塊化的應用
0.7 新版功能.
Flask 用 *藍圖(blueprints)* 的概念來在一個應用中或跨應用制作應用組件和支持通用的模式。藍圖很好地簡化了大型應用工作的方式,并提供給 Flask 擴展在應用上注冊操作的核心方法。一個 Blueprint 對象與 Flask 應用對象的工作方式很像,但它確實不是一個應用,而是一個描述如何構建或擴展應用的*藍圖* 。
### 為什么使用藍圖?
Flask 中的藍圖為這些情況設計:
- 把一個應用分解為一個藍圖的集合。這對大型應用是理想的。一個項目可以實例化一個應用對象,初始化幾個擴展,并注冊一集合的藍圖。
- 以 URL 前綴和/或子域名,在應用上注冊一個藍圖。 URL 前綴/子域名中的參數即成為這個藍圖下的所有視圖函數的共同的視圖參數(默認情況下)。
- 在一個應用中用不同的 URL 規則多次注冊一個藍圖。
- 通過藍圖提供模板過濾器、靜態文件、模板和其它功能。一個藍圖不一定要實現應用或者視圖函數。
- 初始化一個 Flask 擴展時,在這些情況中注冊一個藍圖。
Flask 中的藍圖不是即插應用,因為它實際上并不是一個應用——它是可以注冊,甚至可以多次注冊到應用上的操作集合。為什么不使用多個應用對象?你可以做到那樣(見 [*應用調度*](#) ),但是你的應用的配置是分開的,并在 WSGI 層管理。
藍圖作為 Flask 層提供分割的替代,共享應用配置,并且在必要情況下可以更改所注冊的應用對象。它的缺點是你不能在應用創建后撤銷注冊一個藍圖而不銷毀整個應用對象。
### 藍圖的設想
藍圖的基本設想是當它們注冊到應用上時,它們記錄將會被執行的操作。當分派請求和生成從一個端點到另一個的 URL 時,Flask 會關聯藍圖中的視圖函數。
### 我的第一個藍圖
這看起來像是一個非常基本的藍圖。在這個案例中,我們想要實現一個簡單渲染靜態模板的藍圖:
~~~
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 )。
### 注冊藍圖
那么你如何注冊藍圖?像這樣:
~~~
from flask import Flask
from yourapplication.simple_page import simple_page
app = Flask(__name__)
app.register_blueprint(simple_page)
~~~
如果你檢查已經注冊到應用的規則,你會發現這些:
~~~
[<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 函數。如你所見,它們的前綴是藍圖的名稱,并且用一個點( . )來分割。
不過,藍圖也可以在不同的位置掛載:
~~~
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
當你想要從一個頁面鏈接到另一個頁面,你可以像通常一個樣使用 url_for()函數,只是你要在 URL 的末端加上藍圖的名稱和一個點( . )作為前綴:
~~~
url_for('admin.index')
~~~
此外,如果你在一個藍圖的視圖函數或是模板中想要從鏈接到同一藍圖下另一個端點,你可以通過對端點只加上一個點作為前綴來使用相對的重定向:
~~~
url_for('.index')
~~~
這個案例中,它實際上鏈接到 admin.index ,假如請求被分派到任何其它的admin 藍圖端點。
? 版權所有 2013, Armin Ronacher.
- 歡迎使用 Flask
- 前言
- 給有經驗程序員的前言
- 安裝
- 快速入門
- 教程
- 介紹 Flaskr
- 步驟 0: 創建文件夾
- 步驟 1: 數據庫模式
- 步驟 2: 應用設置代碼
- 步驟 3: 創建數據庫
- 步驟 4: 請求數據庫連接
- 步驟 5: 視圖函數
- 步驟 6: 模板
- 步驟 7: 添加樣式
- 福利: 應用測試
- 模板
- 測試 Flask 應用
- 記錄應用錯誤
- 配置處理
- 信號
- 即插視圖
- 應用上下文
- 請求上下文
- 用藍圖實現模塊化的應用
- Flask 擴展
- 與 Shell 共舞
- Flask 代碼模式
- 大型應用
- 應用程序的工廠函數
- 應用調度
- 使用 URL 處理器
- 部署和分發
- 使用 Fabric 部署
- 在 Flask 中使用 SQLite 3
- 在 Flask 中使用 SQLAlchemy
- 上傳文件
- 緩存
- 視圖裝飾器
- 使用 WTForms 進行表單驗證
- 模板繼承
- 消息閃現
- 用 jQuery 實現 Ajax
- 自定義錯誤頁面
- 延遲加載視圖
- 在 Flask 中使用 MongoKit
- 添加 Favicon
- 數據流
- 延遲請求回調
- 添加 HTTP Method Overrides
- 請求內容校驗碼
- 基于 Celery 的后臺任務
- 部署選擇
- mod_wsgi (Apache)
- 獨立 WSGI 容器
- uWSGI
- FastCGI
- CGI
- 聚沙成塔
- API
- JSON 支持
- Flask 中的設計決策
- HTML/XHTML 常見問題
- 安全注意事項
- Flask 中的 Unicode
- Flask 擴展開發
- Pocoo 風格指引
- Python 3 支持
- 升級到最新版本
- Flask Changelog
- 許可證
- 術語表