[英]Using a dictionary to insert WTForm fields. jinja2.exceptions.UndefinedError: 'wtforms.fields.core.UnboundField object' has no attribute 'label'
I am trying to populate a form in jinja2 using form fields that are in a dictionary. 我正在尝试使用字典中的表单字段填充jinja2中的表单。
#forms.py
class MyForm(FlaskForm):
name = StringField('New Name', validators=[DataRequired()])
fields = {}
fields['Field1'] = StringField('Field 1', validators=[DataRequired()])
fields['Field2'] = StringField('Field 2', validators=[DataRequired()])
#routes.py
@app.route('/test', methods=['GET', 'POST'])
def test():
form = MyForm()
return render_template('_test.html', form=form)
My python code is similar to the above code. 我的python代码类似于以上代码。 If I try to insert the name
field in jinja2 it works fine. 如果我尝试在jinja2中插入name
字段,则效果很好。
{{ form.name.label(class="form-control-label form-control-sm") }}
However, I don't know how to do the same for a field in the fields
dictionary. 但是,我不知道如何对fields
字典中的fields
执行相同的操作。 If I use the following, it gives me an error.( jinja2.exceptions.UndefinedError: 'wtforms.fields.core.UnboundField object' has no attribute 'label'
) 如果使用以下命令,则会给我一个错误。( jinja2.exceptions.UndefinedError: 'wtforms.fields.core.UnboundField object' has no attribute 'label'
)
{{ form.fields['Field1'].label(class="form-control-label form-control-sm") }}
Is it possible to use a dictionary the way I tried to use it or is there an alternative if I have large amount of fields. 是否可以按照我尝试使用字典的方式使用字典,或者如果我有大量字段,是否可以使用字典? My goal in using a dictionary was to use a jinja2 loop to iterate over the dictionary elements to insert all the fields without typing one by one. 我使用字典的目标是使用jinja2循环遍历字典元素以插入所有字段,而无需一个个地键入。
WTForms doesn't support having Fields defined within a class level dictionary attribute. WTForms不支持在类级别的字典属性中定义字段。 The Form base class uses FormMeta (from the same file) as a metaclass to identify unbound WTForm Fields in the class definition and bind them to the current Form and this only discovers class level attributes. Form基类使用FormMeta(来自同一文件)作为元类,以在类定义中标识未绑定的WTForm字段并将其绑定到当前Form,这只会发现类级别的属性。
A minimal working example using a form factory function is below. 下面是使用表单工厂功能的最小工作示例。
The extra form fields are passed in as a lambda function via the field_factory
parameter so that we can delay the creation of the extra fields until after the name
field is created (although any callable that returns a dict will work). 额外的表单字段通过field_factory
参数作为lambda函数传入,以便我们可以将额外字段的创建延迟到name
字段创建之后(尽管返回dict的任何可调用项都可以使用)。 This is needed as WTForms sorts the fields by creation order and not by the order they are supplied in the items
dict inside the make_form()
function. 这是必需的,因为WTForms会根据创建顺序而不是根据make_form()
函数内的items
dict中提供的顺序对字段进行排序。
You can then render them out by iterating over the form instead of specifying a manual order. 然后,您可以通过遍历表单而不是指定手动顺序来呈现它们。
Tested on python 3.7.1. 在python 3.7.1上测试。
from flask import Flask
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired
app = Flask(__name__)
app.config['SECRET_KEY'] = "secret"
def make_form(field_factory, name="MyForm"):
items = dict(name=StringField('New Name', validators=[DataRequired()]),
**field_factory())
my_form = type(name, (FlaskForm,), items)
return my_form
if __name__ == "__main__":
with app.test_request_context("/"):
my_form = make_form(field_factory=lambda: dict(
Field1=StringField('Field 1', validators=[DataRequired()]),
Field2=StringField('Field 2', validators=[DataRequired()])
))
form = my_form()
for field in form:
print(field())
Output 产量
<input id="name" name="name" required type="text" value="">
<input id="Field1" name="Field1" required type="text" value="">
<input id="Field2" name="Field2" required type="text" value="">
<input id="csrf_token" name="csrf_token" type="hidden" value="IjY5ZWMyNWYxYzg3MzU2MTM1MGMyMTI0OTNiOGY1ZTk4OWFkZWU2Y2Qi.XMNLww.uvari0GZi4weboIecdtv9Vl8Jvg">
You can't do this. 你做不到 Fields need to be defined directly in the form itself. 字段需要直接在表单本身中定义。
But you don't need to. 但是您不需要。 If you only want to iterate over the fields, you can just do that, as shown in the WTForms docs . 如果只想遍历字段,则可以执行此操作,如WTForms docs中所示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.