Spec-Zone.ru › Flask 2.1

Использование обработчиков 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–2022 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/2.1.x/patterns/urlprocessors/

Spec-Zone.ru

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