我正在尝试使用 Blueprint 在 Flask 中创建一个“模块化应用程序”。
然而,在创建模型时,我遇到了这样的问题: 为了获得 Flask-SQLAlchemy 提供的 db
对象,我必须引用这个应用程序。我希望能够在多个应用程序中使用一些蓝图(类似于 Django 应用程序的使用方式) ,所以这不是一个好的解决方案。*
db
实例,然后应用程序将其与蓝图的其余部分一起导入。但是,任何其他蓝图希望创建模型需要从 那个蓝图导入,而不是应用程序。我的问题如下:
编辑 : 我自己一直在思考这个问题,这可能与 SQLAlchemy 比 Flask 更相关,因为在声明模型时必须使用
declarative_base()
。不管怎样,那是肯定是从某个地方来的!也许最好的解决方案是将项目的模式定义在一个地方,并像 RubyonRails 那样分散开来。声明性 SQLAlchemy 类定义实际上更像 schema.rb,而不是 Django 的 models.py。我想这也会使迁移(从 Alembic或 移民)更容易使用。
我被要求提供一个示例,所以让我们做一些简单的事情: 假设我有一个描述“平面页面”的蓝图——存储在数据库中的简单的“静态”内容。它使用一个只有简称(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 页面也使用了“在你的蓝图中导入你的应用程序”模式。
* 由于官方文档显示了如何在 Blueprint 中创建路由、视图、模板和资产,而不关心它“在”哪个应用程序中,所以我假设 Blueprint 通常应该可以跨应用程序重用。然而,如果没有独立的模型,这种模块化似乎就没有 那个的用处。
既然 Blueprint 可以不止一次地连接到一个应用程序中,那么在 Blueprint 中使用模型可能就是一种错误的方法?