Routing в Flask
В этой статье мы рассмотрим роутинг URL-адресов в Flask, обсудим ее значение в веб-разработке и дадим представление о том, как она работает.
Мы углубимся в различные аспекты, такие как определение маршрутов, обработка шаблонов динамических URL-адресов, поддержка различных методов HTTP, управление перенаправлениями и ошибками, а также соблюдение рекомендаций по эффективной маршрутизации URL-адресов в Flask.
Flask и URL-маршрутизация
Flask — это популярная веб-инфраструктура для Python, которая позволяет веб-разработчикам легко и эффективно создавать веб-приложения.
Одной из ключевых особенностей Flask является его мощная система маршрутизации URL-адресов.
Маршрутизация URL-адресов — это фундаментальная концепция веб-разработки, которая включает сопоставление (привязку) URL-адресов к определенным функциям или ресурсам в веб-приложении.
Это способ определить, как обрабатываются входящие запросы и какие функции представления. Маршрутизация заключается в том, чтобы принимать запросы и направлять их соответствующим функциям представления, которые обрабатывают их и генерируют желаемый ответ.
Базовая маршрутизация в Flask
Маршрутизация в Flask определяет, как обрабатываются входящие запросы на основе URL-адреса, запрошенного пользователем. Flask использует route()
метод декоратора экземпляра приложения Flask для определения маршрутов, а затем привязывает их к соответствующим функциям представления.
Чтобы продемонстрировать базовую маршрутизацию во Flask, мы начнем с импорта Flask
класса из flask
модуля:
from flask import Flask
Получив Flask
класс, мы можем создать экземпляр приложения и сохранить его в переменной с именем app
. Класс Flask принимает __name__
аргумент, который представляет собой специальную переменную Python, обозначающую имя текущего модуля, содержащего экземпляр приложения Flask:
app = Flask(__name__)
Используя экземпляр приложения, у нас есть доступ к его различным методам и декораторам, которые мы можем использовать для определения маршрутов, обработки запросов и выполнения других задач в нашем веб-приложении. Однако в этом примере нас будет интересовать декоратор route()
, специальный метод, который при применении к функции в Flask превращает ее в функцию представления, которая будет обрабатывать веб-запросы.
В качестве аргументов он принимает обязательный шаблон URL и необязательные HTTP-методы. Декоратор route()
позволяет нам связать шаблон URL с декорированной функцией, по сути говоря, что если пользователь посещает URL-адрес, определенный в декораторе, функция будет активирована для обработки этого запроса:
@app.route('/') def index(): return "This is a basic flask application"
В приведенном выше фрагменте кода к функции применен декоратор route(
/ , что означает, что функция будет обрабатывать запросы к корневому URL-адресу . Поэтому, когда пользователь получает доступ к URL-адресу, Flask запускает функцию, которая возвращает строку «Это базовое приложение Flask», и она будет отображаться в браузере.
Чтобы убедиться, что приложение запускается, когда этот модуль вызывается с помощью Python в командной строке, добавьте проверку if
__name__
:
if __name__ == '__main__': app.run()
Поместив все приведенные выше фрагменты кода в один файл, мы получим следующее приложение Flask:
# app.py from flask import Flask app = Flask(__name__) @app.route('/') def index(): return "This is a basic flask application" if __name__ == '__main__': app.run()
Используя route()
декоратор, мы можем определить маршруты для разных URL-адресов и сопоставить их с соответствующими функциями представления, которые будут генерировать желаемый ответ. Это позволяет нам создавать структурированное и организованное веб-приложение с различными функциями для разных маршрутов.
Переменные правила
В приведенном выше примере мы создали простой URL-адрес. Flask позволяет нам создавать динамические URL-адреса, которые могут реагировать на различные сценарии, вводимые пользователем данные и конкретные требования. Передавая переменные в шаблонах URL, разработчики могут создавать маршруты, которые динамически адаптируются и предоставляют пользователям персонализированный и привлекательный опыт.
При определении маршрутов в Flask мы можем включать переменные заполнители, отмеченные <variable_name>
в шаблоне URL. По умолчанию эти переменные содержат строковые значения. Однако, если нам нужно передать другие типы данных, Flask предоставляет конвертеры, которые позволяют нам указать тип данных, которые нужно захватить, например: <converter:variable_name>
.
Ниже приведен пример диаграммы, показывающей различные переменные URL. URL-адреса меняются в зависимости от значения, которое предоставляет пользователь. Например, мы могли бы каждый раз получать новый продукт, указав другой идентификатор, или мы могли бы показать другой профиль автора, изменив имя пользователя в URL-адресе.
Допустим, у нас есть приложение для ведения блога, и мы хотим создать URL-адрес для представления, показывающего профиль автора. Мы могли бы передать имя пользователя автора следующим образом:
@app.route('/authors/<username>') def show_author(username): return f"Return the author profile of {username}"
В этом примере используется шаблон URL '/authors/<username>'
, где <username>
переменная, которая будет заменена фактическим именем пользователя автора. Он будет передан функции show_author()
в качестве параметра.
Используя это значение, мы можем выполнять дальнейшие действия, например извлекать данные об авторе из базы данных и генерировать ответ на основе информации, которую мы получаем из базы данных.
Мы также можем передать более одной переменной в URL:
@app.route('/posts/<int:post_id>/<slug>') def show_post(post_id, slug): # carry out some processing like # retrieval from a database return f"Post {post_id} - Slug: {slug}"
В этом примере у нас есть шаблон URL с более чем одним переменным правилом. Он также включает преобразователь для в post_id
виде <int:post_id>
, указывающий, что для переменной ожидается целое число. У нас также есть <slug>
, который захватит строку slug для этой переменной.
Поэтому, когда на этот URL-адрес делается запрос, Flask захватывает значения, указанные в URL-адресе, и передает их в качестве аргументов функции show_post()
для дальнейшей обработки. Например, если запрос сделан на /posts/456/flask-intro
, Flask захватит post_id=456
и slug=flask-intro
, и эти значения будут переданы в качестве аргументов функции show_post()
.
Внутри функции мы можем выполнять различные операции, например извлекать соответствующий пост из базы данных на основе значений post_id
и slug
. В примере кода мы просто возвращаем строковый ответ, включающий захваченные значения:
return f"Post {post_id} - Slug: {slug}"
В этом примере показано, как мы можем использовать переменные правила и преобразователи во Flask для создания динамических URL-адресов, которые захватывают различные типы данных — такие как целые числа и строки — и обрабатывают их в функциях представления. Это позволяет нам создавать приложения, которые реагируют на определенный пользовательский ввод и предоставляют настраиваемый контент.
Создание URL
После того, как мы определим наши шаблоны URL-адресов и сопоставим их с функциями просмотра, мы сможем использовать их где-либо еще в нашем коде или в шаблонах вместо жесткого кодирования URL-адресов, которые Flask предоставляет функцию url_for()
. Функция автоматически создаст URL-адрес в зависимости от аргументов, которые мы ей предоставим. Он принимает функцию просмотра имени в качестве первого обязательного аргумента и любое количество необязательных аргументов ключевого слова, каждый из которых соответствует переменной части правила URL.
Создание URL-адресов с использованием этой url_for()
функции имеет несколько преимуществ. В нашем коде будет более наглядно, если url_for(‘login’)
вместо /login
. Мы также сможем изменить наши URL-адреса за один раз, вместо того, чтобы не забывать вручную изменять все жестко запрограммированные URL-адреса. Эта функция также прозрачно и автоматически обрабатывает экранирование специальных символов. Сгенерированные URL-адреса будут абсолютными путями, что устраняет проблему относительных путей в браузерах; независимо от структуры нашего приложения, url_for()
функция справится с этим за нас должным образом.
Давайте воспользуемся url_for()
функцией для создания URL-адресов для функций просмотра, которые мы уже видели выше:
from flask import Flask, url_for app = Flask(__name__) @app.route('/') def index(): return "This is a basic flask application" @app.route('/authors/<username>') def show_author(username): return f"Return the author profile of {username}" @app.route('/post/<int:post_id>/<slug>') def show_post(post_id): return f"Showing post with ID: {post_id}" if __name__ == '__main__': with app.test_request_context(): # Generate URLs using url_for() home_url = url_for('index') profile_url = url_for('show_author', username='antony') post_url = url_for('show_post', post_id=456, slug='flask-intro' ) print("Generated URLs:") print("Home URL:", home_url) print("Author profile URL:", profile_url) print("Post URL:", post_url)
Этот пример демонстрирует использование функции url_for()
для создания URL-адресов. Чтобы использовать функцию, мы импортируем ее из модуля flask
. Он определяет три маршрута: '/'
, '/authors/<username>'
, и '/post/<int:post_id>/<slug>'
.
Внутри if __name__ == '__main__':
блока создается контекст тестового запроса с помощью app.test_request_context()
, чтобы разрешить доступ к url_for()
функции. Он говорит Flask вести себя так, как будто он обрабатывает запрос, даже когда мы используем оболочку.
Затем мы сохраняем сгенерированные URL-адреса в переменных ( home_url
, profile_url
, и post_url
), а затем печатаем их, что дает результат, аналогичный показанному ниже:
Generated URLs: Home URL: / Author profile URL: /authors/antony Post URL: /post/456/flask-intro
Мы также можем использовать url_for()
шаблоны in. Давайте обновим приложение Flask для отображения шаблонов и посмотрим, как мы можем переходить от одного шаблона к другому, генерируя URL-адреса с помощью функции url_for()
:
#app.py from flask import Flask, render_template app = Flask(__name__) @app.route('/') def index(): return render_template("index.html") @app.route('/authors/<username>') def show_author(username): return render_template('profile.html', username=username) if __name__ == '__main__': app.run()
Создайте templates
каталог в корне проекта и создайте следующие два файла.
index.html :
<!DOCTYPE html> <html> <head> <title>Home Page</title> </head> <body> <h1>Welcome to the home page!</h1> <a href="{{ url_for('show_author', username='Antony') }}">Visit Antony's profile</a> </body> </html>
профиль.html :
<!DOCTYPE html> <html> <head> <title>User Profile</title> </head> <body> <h1>Welcome, {{ username }}!</h1> <a href="{{ url_for('index') }}">Go back to home page</a> </body> </html>
В index.html
шаблоне мы используем url_for()
функцию для создания URL-адреса 'profile'
конечной точки и передачи username
аргумента в виде 'Antony'
. Это создаст ссылку на страницу профиля Антония. Точно так же в profile.html
шаблоне мы генерируем ссылку на домашнюю страницу с помощью url_for('index')
.
Когда шаблоны будут обработаны, Flask заменит их {{ url_for(...) }}
соответствующими сгенерированными URL-адресами. Это позволяет динамически генерировать URL-адреса в шаблонах, упрощая создание ссылок на другие маршруты или передачу аргументов этим маршрутам.
Использование url_for()
в шаблонах помогает гарантировать, что сгенерированные URL-адреса являются правильными и удобными в сопровождении, даже если маршруты изменятся в будущем.
Он предоставляет удобный способ создания динамических ссылок, которые адаптируются к текущему состоянию нашего приложения Flask.
В целом, мы видим, что с помощью url_for()
функции мы можем динамически генерировать URL-адреса во Flask на основе конечных точек маршрута (имя функции представления) и других необязательных аргументов. Это обеспечивает гибкий и надежный способ создания URL-адресов, которые адаптируются к конкретным функциям нашего веб-приложения.
HTTP-методы
Веб-приложения используют разные методы HTTP при доступе к URL-адресам, и приложения, созданные с использованием инфраструктуры Flask, не являются исключением. Flask поддерживает различные методы HTTP, такие как GET
, POST
, PUT
, DELETE
и другие. Эти методы определяют действия, которые мы можем выполнять с ресурсами, доступными при доступе к различным URL-адресам, которые мы определили в нашем приложении. Используя различные методы HTTP, мы можем обрабатывать различные типы запросов и выполнять связанные операции в нашем приложении Flask.
Во Flask мы можем определить HTTP-методы, которые может принимать маршрут, используя параметр methods
декоратора route
. Когда мы указываем методы, которые принимает маршрут, Flask гарантирует, что маршрут доступен только для указанных методов.
Вот пример:
from flask import Flask, request app = Flask(__name__) @app.route('/', methods=['GET']) def index(): return "This is the home page" @app.route('/authors', methods=['GET', 'POST']) def authors(): if request.method == 'GET': return "Get all authors" elif request.method == 'POST': # Create a new author return "Create a new author" @app.route('/authors/<int:author_id>', methods=['GET', 'PUT', 'DELETE']) def author(author_id): if request.method == 'GET': return f"Get author with ID: {author_id}" elif request.method == 'PUT': # Update author with ID: author_id return f"Update author with ID: {author_id}" elif request.method == 'DELETE': # Delete author with ID: author_id return f"Delete user with ID: {author_id}" if __name__ == '__main__': app.run()
Этот обновленный код демонстрирует использование методов HTTP во Flask. Он определяет три маршрута: '/'
, '/authors'
, и '/authors/<int:author_id>'
. С каждым маршрутом связаны определенные методы HTTP.
Маршрут '/
разрешает только GET
запросы, и index()
функция обрабатывает GET
запросы к этому маршруту. Он возвращает строку Это домашняя страница при доступе через запрос GET. Мы можем опустить GET
параметр метода, поскольку GET
он используется по умолчанию для всех методов, если не указано иное.
Маршрут '/authors'
разрешает GET
и POST
запросы, и authors()
функция обрабатывает эти запросы. Если метод запроса GET
, он возвращает строку Получить всех авторов . Если метод запроса POST
, он выполняет необходимые действия для создания нового автора и возвращает строку Создать нового автора .
Маршрут '/authors/<int:author_id>'
разрешает GET
, PUT
, и DELETE
запросы, и author()
функция обрабатывает эти запросы. Если метод запроса — GET
, он извлекает автора с указанным идентификатором и возвращает строку ответа. Если метод запроса — PUT
, он обновляет автора с указанным идентификатором и возвращает строку ответа. Если метод запроса DELETE
, он удаляет автора с указанным идентификатором и возвращает строку ответа.
Определяя маршруты с помощью определенных методов HTTP, мы можем создать RESTful API или веб-приложение, которое обрабатывает различные типы запросов и выполняет соответствующие операции со связанными ресурсами.
Редиректы и ошибки
Когда мы рассмотрим концепцию маршрутизации в Flask, нам также необходимо понять, как обрабатывать ошибки. Пользователи будут предоставлять неверные URL-адреса или неполную информацию, что приведет к ошибкам в нашем приложении. Поэтому, чтобы наше приложение было завершено, нам нужно изящно обрабатывать ошибки — либо путем предоставления информативных сообщений, либо путем перенаправления пользователей. Flask предоставляет функции redirect
и abort
.
Функция redirect
используется для перехода пользователя к новому URL-адресу. Его можно использовать в таких сценариях, как успешная отправка формы, аутентификация или когда мы хотим направить пользователя в другой раздел приложения. Он принимает URL-адрес в качестве аргумента или имя маршрута. По умолчанию он возвращает код состояния 302, но мы можем определить свои собственные пользовательские коды состояния.
Для обработки ошибок abort
предусмотрена функция Flask. Он используется для прерывания обработки запроса и возврата ответа об ошибке HTTP. Это позволит нам обрабатывать исключительные случаи или ошибки в нашем приложении и отвечать соответствующим кодом состояния HTTP и страницей ошибки. Используя эту функцию, мы можем обрабатывать различные ошибки в Flask, такие как несанкционированный доступ, недопустимые запросы и другие виды ошибок. Мы можем выбрать соответствующий код состояния HTTP для ошибки, гарантируя, что клиент получит информацию о том, что пошло не так.
Вот пример, который показывает, как использовать две функции:
from flask import Flask, redirect, render_template, request, abort app = Flask(__name__) @app.route('/') def home(): return render_template('home.html') @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': # Perform login authentication username = request.form['username'] password = request.form['password'] # Check if the credentials are valid if username == 'admin' and password == 'password': # Redirect to the user's dashboard on successful login return redirect('/dashboard') else: # Abort the request with a 401 Unauthorized status code abort(401) return render_template('login.html') @app.route('/dashboard') def dashboard(): return render_template('dashboard.html') @app.errorhandler(401) def unauthorized_error(error): return render_template('unauthorized.html'), 401 if __name__ == '__main__': app.run()
В этом примере /login
маршрут обрабатывает как запросы, так GET
и POST
. Когда POST
запрос получен, он выполняет аутентификацию с предоставленными учетными данными. Если учетные данные действительны, пользователь перенаправляется на /dashboard
маршрут с помощью redirect
функции.
Однако, если аутентификация не удалась (например, когда пользователь предоставил неверную информацию для входа), запрос прерывается с кодом состояния 401 Unauthorized с использованием функции abort
. Затем пользователь направляется на страницу ошибки, указанную в unauthorized_error
обработчике ошибок, который отображает unauthorized.html
шаблон и возвращает код состояния 401.
Используя функции redirect
и abort
вместе, мы можем эффективно обрабатывать ошибки аутентификации и перенаправлять пользователей на соответствующие страницы или отображать соответствующие сообщения об ошибках, обеспечивая безопасный и удобный вход в систему.
Лучшие практики для маршрутизации URL-адресов в Flask
Для нашего приложения важно следовать рекомендациям при создании URL-адресов. Вот некоторые из наиболее важных рекомендаций:
- Организуйте URL-адреса и сделайте их легко читаемыми . Сгруппируйте связанные маршруты. Это облегчит навигацию и управление нашей кодовой базой.
- Используйте переменные . Использование переменных в шаблонах URL позволит нашему приложению обрабатывать динамические запросы от пользователей. Для этого мы можем использовать такие правила, как
<variable_name>
. Мы можем связать переменные с преобразователями, чтобы обрабатывать различные типы данных в наших URL-адресах. - Очистить сообщения об ошибках . Убедитесь, что при обработке ошибок в маршрутах мы предоставляем пользователям четкие и информативные сообщения об ошибках. Это будет иметь большое значение для того, чтобы помочь пользователям понять, почему произошли ошибки, и принять соответствующие меры.
- Воспользуйтесь
url_for
функцией . Создание URL-адресов с использованием этойurl_for
функции гарантирует, что наши URL-адреса автоматически генерируются, правильно структурируются и согласуются во всем приложении, что устраняет необходимость их жесткого кодирования.
Следуя этим рекомендациям, мы можем создать хорошо организованную и удобную маршрутизацию URL-адресов в наших приложениях Flask. Это приводит к более чистому коду, улучшенной читабельности, лучшей обработке ошибок и более гибким и структурированным URL-адресам.
Заключение
В заключение, понимание маршрутизации URL-адресов в Flask необходимо для создания удобных и мощных веб-приложений. Определяя маршруты и сопоставляя их с функциями просмотра, это позволяет разработчикам обрабатывать входящие запросы и генерировать соответствующие ответы. В сочетании с переменными мы можем создавать более динамичные шаблоны URL, делая приложение более гибким и адаптируемым.
Понимая принципы маршрутизации URL-адресов в Flask и следуя этим рекомендациям, разработчики могут создавать эффективные, гибкие и удобные веб-приложения.