基于配置文件的动态 WTF 表单
Dynamic WTF Forms based on a config File
我正在尝试根据配置文件生成表单定义。该代码仅用于测试目的:
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 %}
不幸的是,这不起作用:(循环有效,但无法呈现项目。有什么想法吗?
我认为这是您的 class 构造。我相信 wtf 表单需要严格的格式; class 属性是一个 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())
[请注意,您也可以使用 metaclasses 和 __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 %}
您也可以将其用作动态构造函数,因此如果您的产品数量发生变化,请将 N 替换为 4,并将 N 作为函数的参数。 FlaskForms 不允许显式动态构建。
我正在尝试根据配置文件生成表单定义。该代码仅用于测试目的:
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 %}
不幸的是,这不起作用:(循环有效,但无法呈现项目。有什么想法吗?
我认为这是您的 class 构造。我相信 wtf 表单需要严格的格式; class 属性是一个 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())
[请注意,您也可以使用 metaclasses 和 __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 %}
您也可以将其用作动态构造函数,因此如果您的产品数量发生变化,请将 N 替换为 4,并将 N 作为函数的参数。 FlaskForms 不允许显式动态构建。