6

真正缺乏关于如何使用 WTForms 的 FieldList 的文档。所以多亏了互联网,我才能够破解以下内容:

形式:

class BranchForm(Form):
    name = StringField('Name', validators = [Required()])
    equipment = FieldList(SelectField('Equipment', validators=[Required()], coerce=int,
        choices = [(x.id, x.name) for x in Equipment.query.all()]))
    mod = FieldList(StringField('Method of Delivery', validators = [Optional()]))

看法:

def edit_branch(id):
    branch = Branch.query.filter_by(id=id).first()

    #populate data_in to be used by BranchForm
    data_in = []
    for eq_obj in branch.equipment_assoc:
        data_in.append(('equipment', eq_obj.equipment.id))
        data_in.append(('mod', eq_obj.mod))

    editform = BranchForm(data=MultiDict(data_in))

    if editform.validate_on_submit():
        branch.name = editform.name.data

        db.session.add(branch)
        db.session.commit()

        return redirect('/admin/branches/' + str(branch.id))

    editform.name.data = branch.name

    return render_template("branch_edit.html",
        title="Edit Branch",
        branch = branch,
        editform = editform)

让我失望的是,在我使用 WTForm 表单并用我的数据库中的数据填充字段的其他地方(比如编辑表单),我不得不在 form.validate_on_submit() 块之后填充这些表单字段,因为如果不是,那么表单将永远不会更新,因为提交的任何内容都会立即被覆盖。

请参阅“editform.name.data = branch.name”(这是我一直这样做的方式)

从我在网上找到的关于填充 FieldList 的每个示例中,显然必须在实例化期间完成,但表单也必须在 validate_on_submit() 之前实例化,因为 validate_on_submit() 是表单对象的一种方法。

请参阅“editform = BranchForm(data=MultiDict(data_in))”(这就是我看到的所有示例中填充的 FieldLists 的方式。)

如何使用字段列表填充我的表单?

4

2 回答 2

2

好吧,那位朋友帮我解决了这个问题。这就是我最终得到的结果:

形式:

class BranchForm(Form):
    name = StringField('Name', validators = [Required()])
    equipment = FieldList(SelectField('Equipment', validators=[Required()], coerce=int,
        choices = [(x.id, x.name) for x in Equipment.query.all()]))
    mod = FieldList(StringField('Method of Delivery', validators = [Optional()]))

    def populate_assoc(self, branch_obj):
        i = 0
        branch_obj.name = self.name.data
        for assoc_obj in branch_obj.equipment_assoc:
            assoc_obj.equipment_id = self.equipment[i].data
            assoc_obj.mod = self.mod[i].data
            i += 1

看法:

def edit_branch(id):
    branch = Branch.query.filter_by(id=id).first()

    if request.method == 'POST':
        editform = BranchForm()

        if editform.validate_on_submit():
            editform.populate_assoc(branch)

            db.session.add(branch)
            db.session.commit()

            return redirect('/admin/branches/' + str(branch.id))

    #populate data_in to be used 
    data_in = []
    for eq_obj in branch.equipment_assoc:
        data_in.append(('equipment', eq_obj.equipment.id))
        data_in.append(('mod', eq_obj.mod))

    editform = BranchForm(data=MultiDict(data_in))
    editform.name.data = branch.name

    return render_template("branch_edit.html",
        title="Edit Branch",
        branch = branch,
        editform = editform)

诀窍是真正远离使用form.validate_on_submit()作为我的逻辑分隔符,因为它依赖于表单对象。他的想法是使用if request.method == 'POST':来达到这个目的。这样我可以用两种不同的方式实例化我的表单。一个被填充以供显示,另一个仅在请求方法为 POST 时实例化,从而保留表单中提交的信息。

为了完成这项工作,我将 populate_assoc 方法添加到我的表单类中,以便我可以轻松地将表单中的信息放入我的关联模型中。

于 2015-06-19T00:04:31.900 回答
0

WtForms 有一个 populate_obj() 方法。也许这就是你所追求的?

def edit_branch(id):
    branch = Branch.query.filter_by(id=id).first()
    editform = BranchForm(obj=branch)
    if editform.validate_on_submit():
        editform.populate_obj(branch)

        db.session.commit()

        return redirect('/admin/branches/' + str(branch.id))

    return render_template("branch_edit.html",
        title="Edit Branch",
        branch = branch,
        editform = editform)
于 2015-05-29T02:24:23.763 回答