應用程式工廠¶
如果您已經為您的應用程式使用套件和藍圖 (使用藍圖的模組化應用程式),有一些非常好的方法可以進一步改善體驗。常見的模式是在匯入藍圖時建立應用程式物件。但是,如果您將此物件的建立移至函式中,那麼稍後您可以建立此應用程式的多個實例。
那麼,您為什麼要這樣做呢?
測試。您可以擁有具有不同設定的應用程式實例,以測試各種情況。
多個實例。 想像一下,您想要執行同一個應用程式的不同版本。 當然,您可以在您的網路伺服器中設定具有不同配置的多個實例,但是如果您使用工廠,您可以在同一個應用程式程序中執行同一個應用程式的多個實例,這可能會很方便。
那麼,您實際上會如何實作呢?
基本工廠¶
這個想法是在函式中設定應用程式。 像這樣
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_app
或 make_app
,Flask 將自動偵測到該工廠。 您也可以像這樣將引數傳遞給工廠
$ flask --app hello:create_app(local_auth=True) run
然後,在 myapp
中的 create_app
工廠會以關鍵字引數 local_auth=True
呼叫。 有關更多詳細資訊,請參閱 命令列介面。
工廠改進¶
上面的工廠函式不是很聰明,但是您可以改進它。 以下變更很容易實作
使其可以傳入單元測試的配置值,這樣您就不必在檔案系統上建立配置檔案。
在設定應用程式時,從藍圖呼叫函式,以便您有一個地方可以修改應用程式的屬性 (例如,掛鉤請求處理程序之前/之後等)。
如果需要,在建立應用程式時加入 WSGI 中介軟體。