延遲載入視圖¶
Flask 通常與裝飾器一起使用。裝飾器很簡單,而且 URL 就放在呼叫該特定 URL 的函式旁邊。然而,這種方法有一個缺點:這表示所有使用裝飾器的程式碼都必須預先匯入,否則 Flask 永遠不會真正找到您的函式。
如果您的應用程式必須快速匯入,這可能會成為問題。在 Google 的 App Engine 或其他系統等系統上,可能必須這樣做。因此,如果您突然注意到您的應用程式超出此方法的範圍,您可以退回到集中式的 URL 對應。
啟用集中式 URL 對應的系統是 add_url_rule()
函式。您可以使用一個檔案來設定具有所有 URL 的應用程式,而不是使用裝飾器。
轉換為集中式 URL 對應¶
想像一下目前的應用程式看起來有點像這樣
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
pass
@app.route('/user/<username>')
def user(username):
pass
然後,使用集中式方法,您會有一個包含視圖的檔案(views.py
),但沒有任何裝飾器
def index():
pass
def user(username):
pass
然後是一個設定應用程式的檔案,該檔案將函式對應到 URL
from flask import Flask
from yourapplication import views
app = Flask(__name__)
app.add_url_rule('/', view_func=views.index)
app.add_url_rule('/user/<username>', view_func=views.user)
延遲載入¶
到目前為止,我們只拆分了視圖和路由,但模組仍然是預先載入的。訣竅實際上是在需要時載入視圖函式。這可以使用一個輔助類別來完成,該類別的行為就像一個函式,但在首次使用時會在內部匯入真正的函式
from werkzeug.utils import import_string, cached_property
class LazyView(object):
def __init__(self, import_name):
self.__module__, self.__name__ = import_name.rsplit('.', 1)
self.import_name = import_name
@cached_property
def view(self):
return import_string(self.import_name)
def __call__(self, *args, **kwargs):
return self.view(*args, **kwargs)
這裡重要的是正確設定 __module__
和 __name__
。Flask 內部使用它來找出如何命名 URL 規則,以防您沒有為規則本身提供名稱。
然後您可以定義您的中心位置來組合視圖,如下所示
from flask import Flask
from yourapplication.helpers import LazyView
app = Flask(__name__)
app.add_url_rule('/',
view_func=LazyView('yourapplication.views.index'))
app.add_url_rule('/user/<username>',
view_func=LazyView('yourapplication.views.user'))
您可以進一步最佳化這點,減少編寫此程式碼所需的按鍵次數,方法是使用一個函式來呼叫 add_url_rule()
,方法是以專案名稱和點號作為字串的前綴,並根據需要將 view_func
包裝在 LazyView
中。
def url(import_name, url_rules=[], **options):
view = LazyView(f"yourapplication.{import_name}")
for url_rule in url_rules:
app.add_url_rule(url_rule, view_func=view, **options)
# add a single route to the index view
url('views.index', ['/'])
# add two routes to a single function endpoint
url_rules = ['/user/','/user/<username>']
url('views.user', url_rules)
需要記住的一件事是,請求前和請求後處理器必須位於預先匯入的檔案中,才能在第一次請求時正常工作。任何種類的剩餘裝飾器也是如此。