Spec-Zone.ru › Flask 2.0

Использование обработчиков URL

Журнал изменений

В версии 0.7.

Flask 0.7 представляет понятие обработчиков URL. Идея в том, что у вас может быть множество ресурсов с общими частями в URL, которые вы не всегда явно хотите указывать. Например, у вас может быть множество URL, содержащих код языка, но вы не хотите обрабатывать его в каждой функции.

Обработчики URL особенно полезны в сочетании с планами. Мы будем обрабатывать как прикладные, так и специфичные для планов обработчики URL.

Международные 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, но более красивым решением является использование плана. После того, как '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-адреса планов

Поскольку планы могут автоматически добавлять общий префикс ко всем URL, легко сделать это автоматически для каждой функции. Кроме того, планы могут иметь обработчики URL на уровне плана, что устраняет большую часть логики из функции 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–2021 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/2.0.x/patterns/urlprocessors/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API