基于配置文件的动态 WTF 表单



我正在尝试基于配置文件生成表单定义。该代码仅用于测试目的:

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
class B2BForm(FlaskForm):
products = list()
for i in range(0,4):
products.append(StringField('Name asd '+str(i), validators=[DataRequired()]))

然后我渲染我的表单:

{% for p in form.products %}
<div class="form-group">
<label for="password">Label: {{p.label}}</label>
{% for error in p.errors %}
<div style="color: red;">[{{ error }}]</div>
{% endfor %}
</div>
{% endfor %}

不幸的是,这不起作用:(循环有效,但无法呈现项目。有什么想法吗?

我认为这是你的类结构。我相信 wtf 表单需要严格的格式;类属性是wtf_Field而不是字段列表。改为尝试

def index():
def B2BForm():
class _B2BForm(FlaskForm):
prod_list = list()
pass
for i in range(4):
setattr(_B2BForm, 'product_' + str(i), StringField('Name asd ' + str(i), validators=[DataRequired()]))
_B2BForm.prod_list.append(str(i))
return _B2BForm()
return render_template('index.html', form=B2BForm())

[注意你也可以用元类和__metaclass__做这种类型的构造,也可能在def__init__(self)中,但我还没有尝试过这些,更喜欢上面的构造形式]

然后,您需要更改 jinja2 以循环访问您的属性"product_0"、"product_1"等,如下所示:

{% for p_int in form.prod_list %}
<div class="form-group">
<label for="password">Label: {{ form['product_'+p_int].label }}</label>
{% for error in form['product_'+p_int].errors %}
<div style="color: red;">[{{ error }}]</div>
{% endfor %}
</div>
{% endfor %}

您也可以将其用作动态构造函数,因此,如果您的乘积数量发生变化,请将 4 替换为 N,并将 N 作为函数的参数。FlaskForms 不允许显式动态构造。

最新更新