鍍金池/ 教程/ Python/ 使用藍圖的模塊化應用
應用環(huán)境
配置管理
大型應用
可插撥視圖
Flask 方案
在 Shell 中使用 Flask
針對高級程序員的前言
使用藍圖的模塊化應用
部署方式
信號
排除應用錯誤
模板
請求環(huán)境
掌握應用錯誤
測試 Flask 應用
前言
教程
安裝
快速上手
Flask 擴展

使用藍圖的模塊化應用

New in version 0.7.

為了在一個或多個應用中,使應用模塊化并且支持常用方案, Flask 引入了 藍圖 概念。藍圖可以極大地簡化大型應用并為擴展提供集中的注冊入口。

Blueprint 對象與 Flask 應用對象的工作方式類似,但不是一個真正 的應用。它更像一個用于構建和擴展應用的 藍圖 。

為什么使用藍圖?

Flask 中藍圖有以下用途:

  1. 把一個應用分解為一套藍圖。這是針對大型應用的理想方案:一個項目可以實例化一個 應用,初始化多個擴展,并注冊許多藍圖。
  2. 在一個應用的 URL 前綴和(或)子域上注冊一個藍圖。 URL 前綴和(或)子域的參數(shù) 成為藍圖中所有視圖的通用視圖參數(shù)(缺省情況下)。
  3. 使用不同的 URL 規(guī)則在應用中多次注冊藍圖。
  4. 通過藍圖提供模板過濾器、靜態(tài)文件、模板和其他工具。藍圖不必執(zhí)行應用或視圖 函數(shù)。
  5. 當初始化一個 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()

靜態(tài)文件

藍圖的第三個參數(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

如果要創(chuàng)建頁面鏈接,可以和通常一樣使用 url_for() 函數(shù),只是要把藍圖名稱作為端點的前綴,并且用一個點( . )來 分隔:

url_for('admin.index')

另外,如果在一個藍圖的視圖函數(shù)或者被渲染的模板中需要鏈接同一個藍圖中的其他端點,那么使用相對重定向,只使用一個點使用為前綴:

url_for('.index')

如果當前請求被分配到 admin 藍圖端點時,上例會鏈接到 admin.index 。

? Copyright 2013, Armin Ronacher. Created using Sphinx.

上一篇:快速上手下一篇:安裝