使用 wtforms 动态添加输入字段

Posted

技术标签:

【中文标题】使用 wtforms 动态添加输入字段【英文标题】:Add input fields dynamically with wtforms 【发布时间】:2015-04-07 04:09:49 【问题描述】:

我不太确定如何处理这件事。我希望我能到达那里。

例如,我在一个页面上有一个充满地址的表格。这些计数是动态的(可以是 5 或 10 或任何其他计数)。我希望可以在一页上编辑它们。

我的方法是创建一个带有 wtforms 的表单来编辑一个地址并相乘 它在 jinja2 for loop 中并附加到 html 属性 nameid loop.index0 来自迭代,所以我可以手动提取每一行数据 并在我想评估时将其放回我的表单中。

所以这个例子的表格是:

class AdressForm(Form):
    name = TextField()

所以现在我的模板方法如下所示(分解为一个输入字段):

% for address in addresses %
     forms.render_field(addressform.name, id = "name_" ~ loop.index0, 
                          name = "name_" ~ loop.index0, value = address.name) 
% endfor %

(forms.render_field 只是一个宏,用于为 wtforms 的字段函数指定正确的类。就像他们在许多教程中使用的那样)

所以这是行不通的,因为您不能手动将 name 参数传递给字段函数,因为 wtforms 从初始表单的变量名创建 name html-paramter。

那么有没有办法为我要呈现的表单的名称添加前缀或后缀。 或者这是一个 XY 问题,我的方法完全错误。

还是我自己做所有的事情(我真的尽量避免这种情况)

【问题讨论】:

【参考方案1】:

WTForms 有一个名为 FormField 的元字段和另一个名为 FieldList 的元字段。这两者结合在一起会得到你想要的:

class AddressEntryForm(FlaskForm):
    name = StringField()

class AddressesForm(FlaskForm):
    """A form for one or more addresses"""
    addresses = FieldList(FormField(AddressEntryForm), min_entries=1)

要在 AddressesForm 中创建条目,只需使用字典列表:

user_addresses = ["name": "First Address",
                  "name": "Second Address"]
form = AddressesForm(addresses=user_addresses)
return render_template("edit.html", form=form)

然后,在您的模板中,简单地遍历子表单:

% from 'your_form_template.jinja' import forms %
% for address_entry_form in form.addresses %
     address_entry_form.hidden_tag() 
    # Flask-WTF needs `hidden_tag()` so CSRF works for each form #
     forms.render_field(address_entry_form.name) 
% endfor %

WTForms 会自动正确地为名称和 ID 添加前缀,因此当您发回数据时,您将能够获得 form.addresses.data 并返回包含更新数据的字典列表。

【讨论】:

谢谢,它正在工作。只是没有名为name 的表单元素。通过一些尝试和错误address_entry_form.name 将始终由字段名/id 的前缀 哦和type同样的问题 @alexfvolk 你的问题在某处得到解答吗? 要使用 CSRF 令牌,请务必将 hidden_tag() 添加到两个表单中。所以在这个例子中, form.hidden_tag() address_entry_form.hidden_tag() 是必需的。 请注意 Form 已弃用(使用 FlaskForm)。我也认为render_field 方法不再有效。只需致电address_entry_form.name 【参考方案2】:

Sean Vieira's answer 非常适用于 StringFields(以前的 TextField),但对于动态 SelectFields 来说事情变得有点棘手。对于任何对如何使用wtforms 实现动态SelectFields 感兴趣的人,请参阅https://***.com/a/57548509/7781935

【讨论】:

以上是关于使用 wtforms 动态添加输入字段的主要内容,如果未能解决你的问题,请参考以下文章

不是动态选择字段 WTFORMS 的有效选择

Wtforms:如何使用具有动态选择值的选择字段生成空白值

动态选择 WTForms Flask SelectField

使用 VueJs 添加动态输入字段

如何将自动完成添加到动态添加的输入字段?自动完成功能不适用于动态添加的输入字段

如何使用 Json 对象填充动态添加的输入字段