Flask 使用URL處理器

2021-08-23 18:41 更新

Flask 0.7 版引入了 URL 處理器的概念。此概念的意義在于,對于一部分資源, 您并不是很清楚該如何設定其 URL 相同的部分。例如可能有一些 URL 包含了幾個字母 來指定的多國語言語種,但是你不想在每個函數(shù)里都手動識別到底是哪個語言。

搭配 Blueprint 使用時,URL 處理器尤其有用。這里我們將會就具體的應用例子介紹如何使用 URL 處理器和 Blueprint

國際化的應用程序 URL

試想如下一個網頁應用:

from flask import Flask, g

app = Flask(__name__)

@app.route('/<lang_code>/')
def index(lang_code):
    g.lang_code = lang_code
    ...

@app.route('/<lang_code>/about')
def about(lang_code):
    g.lang_code = lang_code
    ...

這可能會產生一大片重復的代碼,因為你必須在每個函數(shù)當中手動處理 ?g? 對象。 當然,你可以使用裝飾器來簡化它,但想要從一個函數(shù)動態(tài)生成 URL 到另一個函數(shù), 仍需詳細地提供這段多國語言代號碼,這將非常地惱人。

對于后者,這就是 ?url_defaults()? 函數(shù)大展神威的地方了! 這些函數(shù)可以自動地將值注入到 ?url_for()? 的調用中去。下面的 代碼檢查多語言代號碼是否在包含各個 URL 值的字典里,以及末端調用的函數(shù)是否接受 ?'lang_code'?

@app.url_defaults
def add_language_code(endpoint, values):
    if 'lang_code' in values or not g.lang_code:
        return
    if app.url_map.is_endpoint_expecting(endpoint, 'lang_code'):
        values['lang_code'] = g.lang_code

URL 映射的函數(shù) ?is_endpoint_expecting()? 可以被用來 識別是否可以給末端的函數(shù)提供一個多國語言代號碼。

相反的函數(shù)是 ?url_value_preprocessor()? 。他們在請求成功 匹配并且能夠執(zhí)行針對 URL 值的代碼時立即執(zhí)行。實際上,他們將信息從包含這些值的 字典當中取出,然后將其放在某個其他的地方:

@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
    g.lang_code = values.pop('lang_code', None)

這樣,您再也不必在每個函數(shù)中都要將 lang_code 分配給 ?g? 了。 您可以進一步的改進它,通過編寫您自己的裝飾器,并使用這些裝飾器為包含多國語言 代號碼的 URL 添加前綴。但是使用藍圖相比起來會更優(yōu)雅一些。一旦 ?'lang_code'? 被從字典里彈出,他就不會在被傳遞到視圖函數(shù)當中。這樣,代碼就可簡化為如下形式:

from flask import Flask, g

app = Flask(__name__)

@app.url_defaults
def add_language_code(endpoint, values):
    if 'lang_code' in values or not g.lang_code:
        return
    if app.url_map.is_endpoint_expecting(endpoint, 'lang_code'):
        values['lang_code'] = g.lang_code

@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
    g.lang_code = values.pop('lang_code', None)

@app.route('/<lang_code>/')
def index():
    ...

@app.route('/<lang_code>/about')
def about():
    ...

多國語言化的 Blueprint URL

因為 Blueprint 能夠自動地為所有 URL 添加一個相同的字符串作為前綴,所以自動處理這些函數(shù)變得非常簡單。 每個藍圖都可以有一個 URL 處理器,即從 ?url_defaults()? 函數(shù)中 移除一整套業(yè)務邏輯,因為它不再檢查URL 是否真正與 ?'lang_code'? 相關:

from flask import Blueprint, g

bp = Blueprint('frontend', __name__, url_prefix='/<lang_code>')

@bp.url_defaults
def add_language_code(endpoint, values):
    values.setdefault('lang_code', g.lang_code)

@bp.url_value_preprocessor
def pull_lang_code(endpoint, values):
    g.lang_code = values.pop('lang_code')

@bp.route('/')
def index():
    ...

@bp.route('/about')
def about():
    ...
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號