Я пытаюсь создать "модульное приложение" в Flask с помощью Blueprints.
При создании моделей, однако, я сталкиваюсь с проблемой обращения к приложению, чтобы получить db
-объект, предоставленный Flask-SQLAlchemy. Я хотел бы иметь возможность использовать некоторые чертежи с несколькими приложениями (аналогично тому, как приложения Django могут быть использованы), поэтому это нехорошее решение. *
- Можно сделать switcharoo и создать Blueprint для создания экземпляра
db
, который приложение затем импортирует вместе с остальной частью чертежа. Но тогда любой другой проект, желающий создавать модели, должен импортировать из этого проекта вместо приложения.
Мои вопросы таковы:
- Есть ли способ, чтобы Blueprints определял модели без какой-либо осведомленности о приложении, которое они используют в дальнейшем, - и есть ли несколько чертежей вместе? Под этим я подразумеваю необходимость импортировать модуль/пакет приложения из вашего Blueprint.
- Неужели я ошибаюсь с самого начала? Являются ли чертежи не независимыми от приложения и не распространяются (приложения la Django)?
- Если нет, то какой шаблон следует использовать для создания чего-то подобного? Расширения фляг? Если вы просто этого не сделаете - и, возможно, централизовать все модели/схемы à la Ruby on Rails?
Изменить: я уже думал об этом сам, и это может быть больше связано с SQLAlchemy, чем с Flask, потому что при объявлении моделей нужно иметь
declarative_base()
. И это должно произойти откуда-то, во всяком случае!Возможно, лучшим решением является определение схемы проекта в одном месте и распространение ее, как это делает Ruby on Rails. Декларативные определения класса SQLAlchemy действительно больше похожи на schema.rb, чем Django models.py. Я предполагаю, что это также облегчило бы использование миграций (от alembic или sqlalchemy-migrate).
Мне было предложено привести пример, поэтому давайте сделаем что-то простое: скажем, у меня есть план, описывающий "flatpages" - простой, "статический" контент, хранящийся в базе данных. Он использует таблицу с простым именем (для URL-адресов), заголовком и телом. Это simple_pages/__init__.py
:
from flask import Blueprint, render_template
from .models import Page
flat_pages = Blueprint('flat_pages', __name__, template_folder='templates')
@flat_pages.route('/<page>')
def show(page):
page_object = Page.query.filter_by(name=page).first()
return render_template('pages/{}.html'.format(page), page=page_object)
Тогда было бы неплохо позволить этой схеме определить свою собственную модель (это в simple_page/models.py
):
# TODO Somehow get ahold of a `db` instance without referencing the app
# I might get used in!
class Page(db.Model):
name = db.Column(db.String(255), primary_key=True)
title = db.Column(db.String(255))
content = db.Column(db.String(255))
def __init__(self, name, title, content):
self.name = name
self.title = title
self.content = content
Этот вопрос связан с:
И другие, но все ответы, похоже, полагаются на импорт экземпляра app db
или на обратное. Страница "Большое приложение, как" вики-страницы также использует шаблон "импортировать ваше приложение в ваш план".
* Поскольку официальная документация показывает, как создавать маршруты, представления, шаблоны и активы в Blueprint, не заботясь о том, какое приложение оно "включено", я предположил, что Blueprints должны, в общем, быть повторно используемыми в приложениях, Однако эта модульность не кажется полезной без наличия независимых моделей.
Так как Blueprints можно подключить к приложению более одного раза, может быть, это неправильный подход к модели в "Чертежах"?