Заводы приложений
Если вы уже используете пакеты и чертежи для своего приложения (Модульные приложения с чертежами), есть несколько отличных способов дальнейшего улучшения опыта. Распространенным шаблоном является создание объекта приложения при импорте чертежа. Но если вы перенесете создание этого объекта в функцию, вы сможете позже создать несколько экземпляров этого приложения.
Так зачем это делать?
- Тестирование. Вы можете иметь экземпляры приложения с различными настройками для тестирования каждого случая.
- Несколько экземпляров. Представьте, что вы хотите запустить различные версии одного и того же приложения. Конечно, вы можете иметь несколько экземпляров с различными конфигурациями, настроенными в вашем веб-сервере, но если вы используете фабрики, вы можете иметь несколько экземпляров одного и того же приложения, работающих в одном процессе приложения, что может быть удобно.
Так как же это фактически реализовать?
Базовые фабрики
Идея состоит в том, чтобы настроить приложение в функции. Например так:
def create_app(config_filename):
app = Flask(__name__)
app.config.from_pyfile(config_filename)
from yourapplication.model import db
db.init_app(app)
from yourapplication.views.admin import admin
from yourapplication.views.frontend import frontend
app.register_blueprint(admin)
app.register_blueprint(frontend)
return app
Недостатки заключаются в том, что вы не можете использовать объект приложения в чертежах во время импорта. Однако вы можете использовать его из запроса. Как получить доступ к приложению с конфигурацией? Используйте current_app:
from flask import current_app, Blueprint, render_template
admin = Blueprint('admin', __name__, url_prefix='/admin')
@admin.route('/')
def index():
return render_template(current_app.config['INDEX_TEMPLATE'])
Здесь мы ищем имя шаблона в конфигурации.
Фабрики и расширения
Предпочтительнее создавать ваши расширения и фабрики приложений таким образом, чтобы объект расширения первоначально не был привязан к приложению.
Используя Flask-SQLAlchemy, как пример, вы не должны делать что-то подобное:
def create_app(config_filename):
app = Flask(__name__)
app.config.from_pyfile(config_filename)
db = SQLAlchemy(app)
Но, скорее, в файле model.py (или эквиваленте):
db = SQLAlchemy()
и в файле application.py (или эквиваленте):
def create_app(config_filename):
app = Flask(__name__)
app.config.from_pyfile(config_filename)
from yourapplication.model import db
db.init_app(app)
Используя этот шаблон проектирования, никакие специфичные для приложения состояния не хранятся в объекте расширения, поэтому один объект расширения может быть использован для нескольких приложений. Для получения дополнительной информации о проектировании расширений обратитесь к Разработка расширений Flask.
Использование приложений
Чтобы запустить такое приложение, вы можете использовать команду flask:
$ export FLASK_APP=myapp $ flask run
$ set -x FLASK_APP myapp $ flask run
> set FLASK_APP=myapp > flask run
> $env:FLASK_APP = "myapp" > flask run
Flask автоматически обнаружит фабрику (create_app или make_app) в myapp. Вы также можете передать аргументы в фабрику, как показано ниже:
$ export FLASK_APP="myapp:create_app('dev')"
$ flask run
$ set -x FLASK_APP "myapp:create_app('dev')"
$ flask run
> set FLASK_APP="myapp:create_app('dev')"
> flask run
> $env:FLASK_APP = "myapp:create_app('dev')"
> flask run
Затем фабрика create_app в myapp вызывается со строкой 'dev' в качестве аргумента. Подробнее см. Интерфейс командной строки.
Улучшения фабрик
Вышеприведенная функция фабрики не очень умная, но вы можете ее улучшить. Следующие изменения легко реализуются:
- Сделайте возможным передавать значения конфигурации для тестов на единицу, чтобы не создавать файлы конфигурации на файловой системе.
- Вызовите функцию из чертежа, когда приложение настраивается, чтобы у вас было место для изменения атрибутов приложения (например, подключение обработчиков запросов до/после).
- Добавьте WSGI-мидлвары при создании приложения, если необходимо.
© 2007–2022 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/2.1.x/patterns/appfactories/