我已经分离了模型文件和使用应用程序工厂。项目结构为像这样:
project/
|-- config.py
|-- core.py # app factory definition which calls db.init_app(app)
|-- database.py # models definition and 'db = SQLAlchemy()' is done here
|-- forms.py # forms definition.
|-- __init__.py # app = create_app() is done here
-- routes.py
我有两种模式:文章和分类。然后,在forms.py
中,我尝试像这样:
class ArticleForm(Form):
title = StringField()
content = TextAreaField()
category = SelectField(
choices=[(c.id, c.name) for c in Category.query.all()]
)
因此,Category.query.all()
在应用程序上下文之外被调用,并引发以下问题:
RuntimeError: application not registered on db instance and no application
bound to current context
那么,我如何用数据库中的现有数据填充SelectField
呢?
您可以使用WTForms的QuerySelectField扩展名:
from flask_wtf import Form
from wtforms.fields import StringField, TextAreaField
from wtforms.ext.sqlalchemy.fields import QuerySelectField
from database import Category
class ArticleForm(Form):
title = StringField()
content = TextAreaField()
category = QuerySelectField(query_factory=lambda: Category.query.all())
这篇博客文章帮助了我,因为我无法获得公认的答案来完成我想要的工作。也去掉了一个导入。
http://kyle.marek-spartz.org/posts/2014-04-04-setting-wtforms-selection-fields-dynamically.html
我用了他的第二个技巧,这个问题看起来像
from flask_wtf import Form
from wtforms.fields import StringField, TextAreaField
from database import Category
class ArticleForm(Form):
title = StringField()
content = TextAreaField()
category = SelectField()
def __init__(self):
super(ArticleForm, self).__init__()
self.category.choices = [(c.id, c.name) for c in Category.query.all()]