我正在尝试使用蓝图在Flask中创建一个“模块化应用程序”。
但是,在创建模型时,我遇到了必须引用该应用程序才能获得db
Flask-SQLAlchemy提供的-object的问题。我希望能够在多个应用程序中使用一些蓝图(类似于Django应用程序的使用方式),所以这不是一个好的解决方案。*
- 可以进行切换,让蓝图创建
db
实例,然后由应用程序将其与蓝图的其余部分一起导入。但是随后,任何其他希望创建模型的蓝图都需要从该蓝图而不是应用程序中导入。
因此,我的问题是:
- 有没有一种方法可以让蓝图定义模型,而又不知道它们以后将使用的应用程序-并且有多个蓝图组合在一起?通过这种方式,我的意思是必须从您的蓝图导入应用程序模块/软件包。
- 我从一开始就错了吗?蓝图是否不是要独立于应用程序并可以重新分发(例如Django应用程序)?
- 如果没有,那么您应该使用什么模式来创建类似的东西?烧瓶扩展?您是否应该简单地做到这一点-也许集中所有模型/方案以及Ruby on Rails?
编辑:我现在一直在考虑这个问题,这可能与SQLAlchemy而不是Flask有关,因为
declarative_base()
在声明模型时必须具有。而这得从什么地方来的,反正!也许最好的解决方案是像Ruby on Rails一样,将项目的模式定义在一个位置并进行分散。声明性SQLAlchemy类定义实际上更像是schema.rb,而不是Django的models.py。我想这也将使使用迁移(从Alembic或sqlalchemy-migrate)更容易。
我被要求提供一个示例,所以让我们做一些简单的事情:假设我有一个描述“ flatpages”的蓝图,“ 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
这个问题与:
以及其他各种选项,但所有答复似乎都依赖于导入应用程序的db
实例,或者相反。在“大应用程序如何” wiki页面也使用“导入您的应用程序在你的蓝图”的格局。
*由于官方文档显示了如何在蓝图中创建路线,视图,模板和资产,而无需关心它在“哪个”应用中,因此我认为,蓝图通常应可在所有应用之间重用。然而,这种模块化似乎并不认为而不让自主车型有用。
由于可以将蓝图多次挂接到应用程序中,因此在蓝图中建立模型可能只是错误的方法?