Модульные приложения с Blueprints
Журнал изменений
Новое в версии 0.7.
Flask использует концепцию blueprints для создания компонентов приложения и поддержки общих шаблонов внутри приложения или между приложениями. Blueprints значительно упрощают работу с большими приложениями и предоставляют централизованный способ для расширений Flask регистрировать операции в приложениях. Объект Blueprint работает аналогично объекту приложения Flask, но он не является приложением. Скорее, это черновик того, как построить или расширить приложение.
Зачем использовать Blueprints?
Blueprints в Flask предназначены для следующих случаев:
- Разделить приложение на набор blueprints. Это идеально подходит для больших приложений; проект может создать объект приложения, инициализировать несколько расширений и зарегистрировать коллекцию blueprints.
- Зарегистрировать blueprint в приложении по префиксу URL и/или поддомену. Параметры в префиксе/поддомене URL становятся общими аргументами представления (с значениями по умолчанию) для всех функций представления в blueprint.
- Зарегистрировать blueprint несколько раз в приложении с различными правилами URL.
- Предоставить фильтры шаблонов, статические файлы, шаблоны и другие утилиты через blueprints. Blueprint не обязательно должен реализовывать приложения или функции представления.
- Зарегистрировать blueprint в приложении для любого из этих случаев при инициализации расширения Flask.
Blueprint в Flask не является подключаемым приложением, потому что он не является приложением — это набор операций, которые могут быть зарегистрированы в приложении, даже несколько раз. Почему бы не иметь несколько объектов приложения? Вы можете это сделать (см. Переключение приложений), но ваши приложения будут иметь отдельные конфигурации и будут управляться на уровне WSGI.
Blueprints вместо этого обеспечивают разделение на уровне Flask, используют общую конфигурацию приложения и могут изменять объект приложения по мере необходимости, будучи зарегистрированными. Недостатком является то, что вы не можете отменить регистрацию blueprint после создания приложения, не уничтожив весь объект приложения.
Концепция Blueprints
Основная концепция blueprints заключается в том, что они записывают операции, которые необходимо выполнить при регистрации в приложении. Flask связывает функции представлений с blueprints при обработке запросов и генерации URL из одной точки входа в другую.
Мой первый Blueprint
Вот что выглядит очень базовый blueprint. В данном случае мы хотим реализовать blueprint, который выполняет простое отображение статических шаблонов:
from flask import Blueprint, render_template, abort
from jinja2 import TemplateNotFound
simple_page = Blueprint('simple_page', __name__,
template_folder='templates')
@simple_page.route('/', defaults={'page': 'index'})
@simple_page.route('/<page>')
def show(page):
try:
return render_template('pages/%s.html' % page)
except TemplateNotFound:
abort(404)
Когда вы связываете функцию с помощью декоратора @simple_page.route, blueprint будет записывать намерение зарегистрировать функцию show в приложении, когда она будет позже зарегистрирована. Кроме того, он будет добавлять префикс к точке входа функции с именем blueprint, которое было предоставлено конструктору Blueprint (в данном случае также simple_page).
Регистрация Blueprints
И как вы регистрируете этот blueprint? Вот так:
from flask import Flask from yourapplication.simple_page import simple_page app = Flask(__name__) app.register_blueprint(simple_page)
Если вы проверите правила, зарегистрированные в приложении, вы найдете следующие:
[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>, <Rule '/<page>' (HEAD, OPTIONS, GET) -> simple_page.show>, <Rule '/' (HEAD, OPTIONS, GET) -> simple_page.show>]
Первое, очевидно, из самого приложения для статических файлов. Другие два — для функции show blueprint simple_page. Как вы можете видеть, они также имеют префикс с именем blueprint и разделены точкой (.).
Однако blueprints также могут быть установлены в разных местах:
app.register_blueprint(simple_page, url_prefix='/pages')
И, конечно же, вот сгенерированные правила:
[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>, <Rule '/pages/<page>' (HEAD, OPTIONS, GET) -> simple_page.show>, <Rule '/pages/' (HEAD, OPTIONS, GET) -> simple_page.show>]
Кроме того, вы можете регистрировать blueprints несколько раз, хотя не каждый blueprint может на это должным образом реагировать. Фактически, это зависит от реализации blueprint, если он может быть установлен более одного раза.
Ресурсы Blueprint
Blueprints также могут предоставлять ресурсы. Иногда вам может потребоваться ввести blueprint только для ресурсов, которые он предоставляет.
Папка ресурсов Blueprint
Как и для обычных приложений, blueprints считаются содержащимися в папке. Хотя несколько blueprints могут происходить из одной папки, это необязательно и обычно не рекомендуется.
Папка определяется из второго аргумента Blueprint, который обычно равен __name__. Этот аргумент указывает, какой логический модуль или пакет Python соответствует blueprint. Если он указывает на фактический пакет Python, этот пакет (который является папкой в файловой системе) является папкой ресурсов. Если это модуль, папка, в которой находится модуль, будет папкой ресурсов. Вы можете получить доступ к свойству Blueprint.root_path , чтобы увидеть, какая это папка ресурсов:
>>> simple_page.root_path '/Users/username/TestProject/yourapplication'
Для быстрого открытия исходных файлов из этой папки вы можете использовать функцию open_resource():
with simple_page.open_resource('static/style.css') as f:
code = f.read()
Статические файлы
Blueprint может экспонировать папку со статическими файлами, предоставив путь к папке в файловой системе через параметр static_folder. Он может быть абсолютным путем или относительным к папке blueprint:
admin = Blueprint('admin', __name__, static_folder='static')
По умолчанию правая часть пути — это то, где он экспонируется в веб-приложении. Поскольку папка здесь называется static, она будет доступна по адресу blueprint + /static. Скажем, blueprint зарегистрирован для /admin, папка со статическими файлами будет находиться по адресу /admin/static.
Точка входа называется blueprint_name.static, поэтому вы можете генерировать URL-адреса к ней так же, как и к папке со статическими файлами приложения:
url_for('admin.static', filename='style.css')
Шаблоны
Если вы хотите, чтобы blueprint экспонировал шаблоны, вы можете сделать это, предоставив параметр template_folder конструктору Blueprint:
admin = Blueprint('admin', __name__, template_folder='templates')
Для статических файлов путь может быть абсолютным или относительным к папке ресурсов blueprint.
Папка шаблонов добавляется в путь поиска шаблонов, но имеет более низкий приоритет, чем фактическая папка шаблонов приложения. Таким образом, вы легко можете переопределить шаблоны, предоставляемые blueprint, в фактическом приложении. Это также означает, что если вы не хотите, чтобы шаблон blueprint случайно переопределялся, убедитесь, что ни у одного другого blueprint или фактического приложения шаблона нет такого же относительного пути. Когда несколько blueprints предоставляют один и тот же относительный путь к шаблону, первый зарегистрированный blueprint имеет приоритет перед другими.
Итак, если у вас есть blueprint в папке yourapplication/admin и вы хотите отобразить шаблон 'admin/index.html', и вы предоставили templates как template_folder, вам нужно создать файл, подобный этому: yourapplication/admin/templates/admin/index.html. Причина дополнительной папки admin заключается в том, чтобы избежать переопределения нашего шаблона шаблоном с именем index.html в фактической папке шаблонов приложения.
Еще раз подчеркнем: если у вас есть blueprint с именем admin и вы хотите отобразить шаблон под названием index.html, который специфичен для этого blueprint, лучше всего расположить ваши шаблоны так:
yourpackage/
blueprints/
admin/
templates/
admin/
index.html
__init__.py
А затем, когда вы захотите отобразить шаблон, используйте admin/index.html в качестве имени для поиска шаблона. Если у вас возникнут проблемы с загрузкой правильных шаблонов, включите переменную конфигурации EXPLAIN_TEMPLATE_LOADING, которая укажет Flask на вывод шагов, которые он выполняет для поиска шаблонов при каждом вызове render_template.
Создание URL-адресов
Если вы хотите создать ссылку с одной страницы на другую, вы можете использовать функцию url_for() так же, как обычно, но префикс URL-адреса с именем blueprint и точкой (.):
url_for('admin.index')
Кроме того, если вы находитесь в функции представления blueprint или рендеренд шаблоне и хотите создать ссылку на другую точку входа в тот же blueprint, вы можете использовать относительные перенаправления, добавив только точку перед точкой входа:
url_for('.index')
Это приведет к ссылке на admin.index , например, в случае, если текущий запрос был передан в любую другую точку входа blueprint.
Обработчики ошибок
Blueprints поддерживают декоратор errorhandler, как и объект приложения Flask, поэтому легко создать специфичные для Blueprint страницы ошибок.
Вот пример для исключения «404 Page Not Found»:
@simple_page.errorhandler(404)
def page_not_found(e):
return render_template('pages/404.html')
Дополнительную информацию об обработке ошибок см. в разделе Настраиваемые страницы ошибок.
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/0.12.x/blueprints/