我有一个工作示例 Flask-Admin 应用程序 on GitHub它查询 View (本身基于 MySQL 的 information_schema.TABLES
)以动态更新 ModelView 的 column_labels
和 column_descriptions
属性。还有一个小的模板修改,用于将工具提示添加到包含来自数据库的列注释的标题行。
我付出了很多努力来解决这个问题,因为在我的 Python 代码中重新键入列描述似乎很愚蠢,因为它们已经使用 COMMENT< 输入到数据库中
创建表时的 SQL 关键字。
在简单的测试应用程序中,一切都按预期工作;我收到了 model
和 session
参数给 ModelView
的 __init__
方法,我使用 session
查询其他模型的列标签/评论,更新 View 上的 self.column_labels
和 self.column_descriptions
,然后调用 super ()
。
然而,在更复杂的应用程序中,我得到了可怕的 RuntimeError: No application found。当我尝试在
。我要注意的演示应用程序和我的“真实”应用程序之间的唯一显着区别是我导入了一个在另一个 ModelView
的 __init__
方法中查询其他模型时,要么在 View 函数内部工作,要么推送应用程序上下文.py
文件中实例化的 SQLAlchemy
对象,然后调用它的 init_app()
在我的 app.py
中将其连接到 Flask 实例。
编辑:正是问题所在; SQLAlchemy
实例以通常的方式创建,在 Flask-SQLAlchemy Quickstart 中演示在他们的 __init__()
中获得一个合适的 Flask 应用程序实例;当我使用 db.init_app(app)
时,我得到了 No application found
错误。
我的问题是:Flask-Admin ModelView
何时开始存在于 Flask 应用程序上下文中? 为什么 import db from something 的情况不同.py; db.init_app(app)
与 db = SQLAlchemy(app)
?有什么方法可以跟踪 Flask 应用程序的启动过程并挂接到那个确切的时刻,以便我可以看到这里发生了什么?
这是涉及的两个基本部分(完整源代码 for each 在 GitHub 上,如上所述):
提供“元数据”列的模型,包括评论
# models.py
# [SQLALchemy imports and declaration of 'Base']
class ColumnProperty(Base):
# this view is based on MySQL's 'information_schema.TABLES'
__tablename__ = 'v_column_properties'
parent_table = Column(String(64), primary_key=True)
name = Column(String(64), primary_key=True)
# [some fields elided]
comment = Column(String(1024)) # type: str
和
实例化时查询上述模型的ModelView
# views.py
from flask_admin.contrib.sqla import ModelView
class TestView(ModelView):
def __init__(self, model, session, **kwargs):
from models import ColumnProperty as cp
descriptions = {}
q = session.query(cp).filter(cp.parent_table==model.__tablename__)
for row in q.all():
descriptions[row.name] = row.comment
self.column_descriptions = descriptions
super(TestView, self).__init__(model, session, **kwargs)
最佳答案
我会覆盖 ModelView
的 render
方法并在那里设置您的 column_descriptions
。显然,您可以设置某种缓存机制来减少数据库查询的数量。
类似(完全未经测试)- 注意在查询中使用 self.session
:
# views.py
from flask_admin.contrib.sqla import ModelView
class TestView(ModelView):
def render(self, template, **kwargs):
from models import ColumnProperty as cp
descriptions = {}
q = self.session.query(cp).filter(cp.parent_table==model.__tablename__)
for row in q.all():
descriptions[row.name] = row.comment
self.column_descriptions = descriptions
super(TestView, self).render(template, **kwargs)
关于python - 我的 Flask-Admin ModelView 的 __init__ 没有应用程序上下文——它通常什么时候获得一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50459142/