Если вы уже создаете веб-приложения, используя структуру пакета и схемы blueprint
, то есть несколько способов улучшить свой опыт. Распространенным шаблоном проектирования является создание объекта приложения при импорте схемы blueprint
. Но если переместить создание этого объекта в функцию, то можно позже создать несколько экземпляров этого приложения.
А зачем это делать?
Итак, как это реализовать?
Базовое использование фабрики приложений во Flask довольно простое. Идея состоит в том, чтобы настроить приложение в функции. Как это:
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
Недостатком является то, что нельзя использовать объект приложения в схемах приложения blueprint
во время импорта, но можно его использовать из запроса. Как получить доступ к приложению из конфигурацией? Используйте flask.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'])
Здесь ищется имя шаблона в current_app.config
.
Желательно создавать расширения/дополнения и фабрики приложений так, чтобы объект расширения/дополнения изначально не привязывался к приложению.
Используя 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
# инициализация `Flask-SQLAlchemy`
db.init_app(app)
При использовании этого шаблона проектирования в объекте расширения Flask-SQLAlchemy
не сохраняется состояние, зависящее от приложения, поэтому один объект расширения может использоваться для нескольких приложений.
Чтобы запустить такое приложение, можно использовать команду flask
:
# Bash
$ export FLASK_APP=myapp
$ flask run
# CMD
> set FLASK_APP=myapp
> flask run
# Powershell
> $env:FLASK_APP = "myapp"
> flask run
Flask автоматически обнаружит фабрику (create_app
или make_app
) в myapp
. Также можно передать аргументы фабрике следующим образом:
# Bash
$ export FLASK_APP="myapp:create_app('dev')"
$ flask run
# CMD
> set FLASK_APP="myapp:create_app('dev')"
> flask run
# Powershell
> $env:FLASK_APP = "myapp:create_app('dev')"
> flask run
Затем в myapp
вызывается фабрика create_app
со строкой 'dev'
в качестве аргумента.
Вышеупомянутая фабричная функция не очень умна, но можно ее улучшить. Следующие изменения легко реализовать:
blueprint
при настройке приложения, чтобы было место для изменения атрибутов приложения (например, подключение обработчиков запросов до/после и т. д.)