如何根据 flask 和 flask-sqlalchemy 的动态属性使用 wtforms SelectField?

How to use wtforms SelectField depending on dynamic attributes with flask & flask-sqlalchemy?

在一个基本上有两个属性的 Flask 应用程序中,这些属性具有这样的基本关系,例如:

models.py

from . import db

class ProjectModel(db.Model):
    __tablename__ = "projectmodels"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    projects = db.relationship("Project", backref="projectmodel", lazy="select")

class Project(db.Model):
    __tablename__ = "projects"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    project_model_id = db.Column(db.Integer, db.ForeignKey("projectmodels.id"), nullable=False)

当创建一个 Project 对象时 wtforms 将有一个 SelectField 取决于 projectmodels 在数据库上。

我的解决方案是定义函数 returns a list for SelectField[choices] :

forms.py

from . import db
from wtforms import *

def projectmodels():
    models = ProjectModel.query.all()
    models_l = list()
    for model in models:
        models_l.append((str(model.id), model.name))
    return models_l

class AddProjectForm(Form):
    name = StringField(label="Project Name")
    project_model = SelectField("Project Model", 
                    choices=projectmodels())

虽然 flask app 运行ning,SelectField 列出了 app 运行 之前数据库中的所有对象。但是在该会话期间,如果添加了任何其他项目模型,它将不会列出它们,直到应用重新运行。

routes.py@app.route 部分中使所有表格都有效可以解决此问题,但我认为这不是最佳解决方案。

解决这个问题的方法是什么?

    def __init__(self, *args, **kwargs):
        super(AddProjectForm, self).__init__(*args, **kwargs)
        self.project_model.choices = [(a.id, a.name) for a in ProjectModel.query.order_by(ProjectModel.id)]

AddProjectForm class 下初始化它解决了我的问题。