Во Flask создание URL осуществляется автоматически с использованием функции url_for(), доступной в flask. Прямое указание ссылок в шаблонах или представлениях может вызвать трудности. Допустим, структуру URL в блоге поменяли с /<id>/<post-title>/ на /<id>/post/<post-title>/. Если ссылки были заданы вручную, потребуется переписывать каждую из них. Благодаря функции url_for(), достаточно изменить структуру один раз.

Функция url_for() требует указать конечную точку и возвращает строку с URL. Конечная точка обычно — это название функции представления. Вот пример из main2.py, где определен корневой маршрут (/):

#...
@app.route('/')
def index():
    return render_template('index.html', name='Jerry')
#...
        

Чтобы получить корневой URL, вызовите url_for() как url_for('index'), и вы получите '/'. Вот пример использования url_for() в интерактивной консоли:

>>> from main2 import app
>>> from flask import url_for
>>>
>>> with app.test_request_context('/api'): # путь /api выбран произвольно
...     url_for('index')
...
'/'
>>>

Важно создать контекст запроса (вместе с приложением), прежде чем работать в консоли. В противном случае при вызове url_for() возникнет ошибка. Дополнительная информация о контекстах во Flask доступна здесь .

Если функция url_for() не может создать URL, это вызывает исключение BuildError.

>>>
>>> with app.test_request_context('/api'):
... url_for('/api')
...
Traceback (most recent call last):
...
werkzeug.routing.BuildError: Could not build url for endpoint '/api
Did you mean 'static' instead?
>>>

Для создания абсолютного URL передайте _external=True в функции url_for():

>>>
>>> with app.test_request_context('/api'):
...     url_for('index', _external=True)
...
'http://localhost:5000/'
>>>

При использовании redirect(), рекомендуется указывать URL через url_for(). Вот как можно это сделать:

@app.route('/admin/')
def admin():
    if not loggedin:
        return redirect(url_for('login')) # если не залогинен, выполнять редирект на страницу входа
    return render_template('admin.html')

Чтобы создать URL с динамическими компонентами, укажите их как именованные аргументы. Рассмотрим следующие примеры:

>>>
>>> with  app.test_request_context('/api'):
...     url_for('user_profile', user_id = 100)
...
'/user/100/'
>>>
>>> with  app.test_request_context('/api'):
...     url_for('books', genre='biography')
...
'/books/biography/'
>>>

При указании дополнительных аргументов в url_for(), они будут преобразованы в параметры строки запроса URL.

>>>
>>> with  app.test_request_context('/api'):
...     url_for('books', genre='biography', page=2, sort_by='date-published')
...
'/books/biography/?page=2&sort_by=date-published'
>>>

Функцию url_for() можно использовать и в шаблонах. Для генерации URL в шаблоне запишите вызов функции в скобках {{ … }}:

<a href="{{ url_for('books', genre='biography') }}">Books</a>

Результат:

<a href="/books/biography/">Books</a>

Вопросы для самопроверки:

  1. Для чего используется функция url_for() в Flask?
  2. Какие параметры необходимо указать при вызове функции url_for()?
  3. Как создать абсолютный URL с помощью url_for()?
  4. Как добавить динамические компоненты к URL при помощи url_for()?
  5. Как можно использовать url_for() в шаблонах Flask?