Если вы уже создаете веб-приложения, используя структуру пакета и схемы 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
при настройке приложения, чтобы было место для изменения атрибутов приложения (например, подключение обработчиков запросов до/после и т. д.)