應用程式工廠

如果您已經為您的應用程式使用套件和藍圖 (使用藍圖的模組化應用程式),有一些非常好的方法可以進一步改善體驗。常見的模式是在匯入藍圖時建立應用程式物件。但是,如果您將此物件的建立移至函式中,那麼稍後您可以建立此應用程式的多個實例。

那麼,您為什麼要這樣做呢?

  1. 測試。您可以擁有具有不同設定的應用程式實例,以測試各種情況。

  2. 多個實例。 想像一下,您想要執行同一個應用程式的不同版本。 當然,您可以在您的網路伺服器中設定具有不同配置的多個實例,但是如果您使用工廠,您可以在同一個應用程式程序中執行同一個應用程式的多個實例,這可能會很方便。

那麼,您實際上會如何實作呢?

基本工廠

這個想法是在函式中設定應用程式。 像這樣

def create_app(config_filename):
    app = Flask(__name__)
    app.config.from_pyfile(config_filename)

    from yourapplication.model import db
    db.init_app(app)

    from yourapplication.views.admin import admin
    from yourapplication.views.frontend import frontend
    app.register_blueprint(admin)
    app.register_blueprint(frontend)

    return app

缺點是您無法在匯入時在藍圖中使用應用程式物件。 但是,您可以從請求內部使用它。 您如何存取具有配置的應用程式? 使用 current_app

from flask import current_app, Blueprint, render_template
admin = Blueprint('admin', __name__, url_prefix='/admin')

@admin.route('/')
def index():
    return render_template(current_app.config['INDEX_TEMPLATE'])

在這裡,我們在配置中查找範本的名稱。

工廠 & 擴展

最好建立您的擴展和應用程式工廠,以便擴展物件最初不會綁定到應用程式。

Flask-SQLAlchemy 為例,您不應該做類似的事情

def create_app(config_filename):
    app = Flask(__name__)
    app.config.from_pyfile(config_filename)

    db = SQLAlchemy(app)

而是,在 model.py (或等效檔案) 中

db = SQLAlchemy()

以及在您的 application.py (或等效檔案) 中

def create_app(config_filename):
    app = Flask(__name__)
    app.config.from_pyfile(config_filename)

    from yourapplication.model import db
    db.init_app(app)

使用這種設計模式,應用程式特定的狀態不會儲存在擴展物件上,因此一個擴展物件可以用於多個應用程式。 有關擴展設計的更多資訊,請參閱 Flask 擴展開發

使用應用程式

要執行這樣的應用程式,您可以使用 flask 命令

$ flask --app hello run

如果工廠在 hello 中被命名為 create_appmake_app,Flask 將自動偵測到該工廠。 您也可以像這樣將引數傳遞給工廠

$ flask --app hello:create_app(local_auth=True) run

然後,在 myapp 中的 create_app 工廠會以關鍵字引數 local_auth=True 呼叫。 有關更多詳細資訊,請參閱 命令列介面

工廠改進

上面的工廠函式不是很聰明,但是您可以改進它。 以下變更很容易實作

  1. 使其可以傳入單元測試的配置值,這樣您就不必在檔案系統上建立配置檔案。

  2. 在設定應用程式時,從藍圖呼叫函式,以便您有一個地方可以修改應用程式的屬性 (例如,掛鉤請求處理程序之前/之後等)。

  3. 如果需要,在建立應用程式時加入 WSGI 中介軟體。