Использование обработчиков URL
Журнал изменений
Новая версия 0.7.
Flask 0.7 представляет концепцию обработчиков URL. Идея заключается в том, что у вас может быть множество ресурсов с общими частями в URL, которые вы не всегда явно хотите предоставлять. Например, у вас может быть множество URL, содержащих код языка, но вы не хотите обрабатывать его в каждой функции самостоятельно.
Обработчики URL особенно полезны при использовании с blueprints. Здесь мы будем рассматривать как прикладные обработчики 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
...
Это очень много повторений, так как вам нужно обрабатывать установку кода языка на объекте g в каждой функции. Конечно, декоратор мог бы упростить это, но если вы хотите генерировать URL из одной функции в другую, вам все равно нужно явно указать код языка, что может быть неудобно.
В последнем случае на помощь приходят функции url_defaults(). Они могут автоматически вставлять значения в вызов url_for() автоматически. Приведенный ниже код проверяет, не содержится ли код языка в словаре значений URL, и если конечная точка требует значения с именем '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
Метод 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 с кодом языка, но более красивое решение — использовать blueprint. После того, как '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 на уровне blueprint, что значительно уменьшает логику в функции url_defaults(), поскольку ей больше не нужно проверять, действительно ли 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():
...
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/0.12.x/patterns/urlprocessors/