import flask flask.url_for(endpoint, **values)
endpoint
- конечная точка URL (имя функции-представления),**values
- переменные аргументы правила URL-адреса._external
- если установлено значение True
, то создается абсолютный URL. Адрес сервера можно изменить с помощью переменной конфигурации SERVER_NAME
, которая возвращается к заголовку Host
, а затем к IP и порту запроса._scheme
- строка, определяющая желаемую URL-схему. При этом аргумент _external
должен иметь значение True
, в противном случае возникает ошибка ValueError
. Поведение по умолчанию использует ту же схему, что и текущий запрос, или если контекст запроса недоступен, то PREFERRED_URL_SCHEME
. Может быть установлен в пустую строку ''
для построения URL-адресов, относящихся к протоколу._anchor
- если предусмотрено, то добавляется в качестве привязки к URL-адресу._method
- если предусмотрено, то явно указывает HTTP-метод.BuildError
.Функция url_for()
создает URL-адрес для заданной конечной точки endpoint
(функции-представления).
Ключевые аргументы **values
, которые неизвестны целевой конечной точке endpoint
(функции-представления), добавляются к сгенерированному URL-адресу в качестве параметров запроса как '?name=val&name1=val1'
. Если значение параметра запроса является None
(foo=None
), то вся пара пропускается.
Если flask.url_for()
генерирует URL-адрес для схемы blueprint
, то для одной и той же схемы можно сокращать ссылки, добавив к локальной конечной точке endpoint
префикс точки .
. Например выражение url_for('.index')
будет ссылаться на функцию index()
, локальную для текущего blueprint
.
Значения конфигурации APPLICATION_ROOT
и SERVER_NAME
используются только при генерации URL-адресов вне контекста запроса.
Для интеграции приложений во Flask, есть перехватчик ошибок построения URL через Flask.url_build_error_handlers
. Функция url_for()
приводит к ошибке BuildError
, когда текущее приложение не имеет URL-адреса для данной конечной точки endpoint
и значений **values
. Когда это происходит, то flask.current_app()
вызывает свои app.url_build_error_handlers
, если он не равен None
, который может возвращать строку для использования в качестве результата url_for()
(вместо url_for()
по умолчанию, вызывает исключение BuildError
) или повторно вызывать исключение. Пример:
def external_url_handler(error, endpoint, values): "Ищет внешний URL-адрес, когда url_for не может создать URL-адрес." # Пример подключения `build_error_handler`. # Здесь `lookup_url` - это созданная служебная функция, # которая ищет конечную точку во внешнем реестре URL-адресов. url = lookup_url(endpoint, **values) if url is None: # Внешний поиск URL-адреса не дал результатов. # Повторно вызываем `BuildError` в контексте исходной трассировки. exc_type, exc_value, tb = sys.exc_info() if exc_value is error: raise exc_type(exc_value).with_traceback(tb) else: raise error # `url_for()` будет использовать этот результат вместо исключения `BuildError` return url # подключение функции `external_url_handler` app.url_build_error_handlers.append(external_url_handler)
Например, error
- это экземпляр BuildError
, а конечная точка endpoint
и значения values
- это аргументы, переданные в url_for()
. Обратите внимание, что код предназначен для создания URL-адресов вне текущего приложения, а не для обработки ошибок 404 NotFound
.
Что бы автоматически создать URL-адрес для функций-представлений, декорированных @app.route()
, необходимо использовать url_for()
. В качестве первого аргумента она принимает имя функции-представления и любое количество ключевых аргументов, каждый из которых соответствует изменяемой части URL-адреса (например, в URL '/user/<username>'
- изменяемая часть username
). Если указываются ключевые аргументы, которые отсутствует в изменяемых частях URL-адреса, то все они добавляются к URL в качестве параметров запроса (например, ?next=then
).
>>> from flask import Flask, url_for >>> app = Flask(__name__) >>> @app.route('/') ... def index(): pass ... >>> @app.route('/login') ... def login(): pass ... >>> @app.route('/user/<username>') ... def profile(username): pass ... >>> with app.test_request_context(): ... print(url_for('index')) ... print(url_for('login')) ... # переменной `next` нет в маршруте `/login` ... print(url_for('login', next='then')) ... print(url_for('profile', username='admin')) ... # / # /login # /login?next=then # /user/admin
В примере использован метод app.test_request_context()
, который заставляет Flask вести себя так, как будто он обрабатывает запрос, даже при взаимодействии с ним через интерпретатор Python.
jinja2
.Для создания ссылки на URL-адрес в шаблоне jinja2
необходимо сделать что-то подобное:
<a href="{{ url_for('get_post', year=year, month=month, title=title)}}"> {{ title }} </a>
Если URL-адрес содержит много ключевых аргументов и url_for()
желательно использовать с распаковкой ключевых аргументов, в стиле:
{{ url_for('get_post', **post) }}
То необходимо изменить код на что-то вроде этого:
@route('/posts/') def get_all_posts(): # допустим, что используется модель БД models = database_posts posts = [] for model in models: posts.append(dict(year=model.year, month=model.month, title=model.title)) return render_template('posts.html', posts=posts)
Тогда код шаблона может выглядеть как-то так:
{% for post in posts %} <a href="{{ url_for('get_post', **post) }}"> {{ post['title'] }} </a> {% endfor %}
На этом этапе можно создать метод для модели, что-бы каждый раз в коде не нужно было превращать его в словарь.
Для обработки статических файлов настоятельно рекомендуется использовать диспетчер активов, такой как
Flask-Assets
, чтобы обслуживать статику с помощьюFlask
, смотрите материал "Как обслуживать статические файлы в Flask Python".