Использование процессоров URL
Журнал изменений
Новое в версии 0.7.
Flask 0.7 представляет концепцию процессоров URL. Идея заключается в том, что у вас может быть множество ресурсов с общими частями в URL, которые вы не всегда явно хотите предоставлять. Например, у вас может быть множество URL-адресов, содержащих код языка, но вы не хотите обрабатывать его в каждой отдельной функции.
Процессоры URL особенно полезны в сочетании с blueprints. Здесь мы будем рассматривать как специфичные для приложения процессоры URL, так и специфичные для blueprints.
Международные 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
...
Это очень много повторений, так как вам нужно обработать установку кода языка в объекте g в каждой отдельной функции. Конечно, можно использовать декоратор, чтобы упростить это, но если вы хотите сгенерировать URL-адреса из одной функции в другую, вам по-прежнему нужно явно указать код языка, что может быть неудобно.
В последнем случае на помощь приходят функции url_defaults(). Они могут автоматически вставлять значения в вызов url_for(). Приведенный ниже код проверяет, не указан ли код языка в словаре значений URL и хочет ли конечная точка значения с именем %%%CODE_BLOCK_4%%:
@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
Метод is_endpoint_expecting() карты URL можно использовать для определения того, имеет ли смысл предоставить код языка для данной конечной точки.
Обратной стороной этих функций являются url_value_preprocessor(). Они выполняются сразу после сопоставления запроса и могут выполнять код на основе значений URL. Идея заключается в том, чтобы извлечь информацию из словаря значений и поместить ее в другое место:
@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
g.lang_code = values.pop('lang_code', None)
Таким образом, вам больше не нужно выполнять присваивание lang_code объекту g в каждой функции. Вы можете еще больше улучшить это, написав собственный декоратор, который добавляет префикс кода языка к URL-адресам, но более изящным решением является использование blueprints. После извлечения 'lang_code' из словаря значений он больше не будет передаваться в функцию представления, что приводит к такому коду:
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():
...
Международные URL-адреса blueprints
Поскольку blueprints могут автоматически добавлять общий префикс ко всем URL-адресам, легко автоматически сделать это для каждой функции. Кроме того, blueprints могут иметь собственные процессоры URL для blueprints, что устраняет значительную часть логики из функции url_defaults(), поскольку ей больше не нужно проверять, действительно ли URL-адрес заинтересован в параметре %%%CODE_BLOCK_14%%:
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():
...
© 2007–2022 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/2.3.x/patterns/urlprocessors/