Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用字典插入WTForm字段。jinja2.exceptions.UndelineError:“wtforms.fields.core.UnboundField对象”没有属性“label”_Python_Html_Flask_Jinja2_Wtforms - Fatal编程技术网

Python 使用字典插入WTForm字段。jinja2.exceptions.UndelineError:“wtforms.fields.core.UnboundField对象”没有属性“label”

Python 使用字典插入WTForm字段。jinja2.exceptions.UndelineError:“wtforms.fields.core.UnboundField对象”没有属性“label”,python,html,flask,jinja2,wtforms,Python,Html,Flask,Jinja2,Wtforms,我正在尝试使用字典中的表单字段填充jinja2中的表单 #forms.py class MyForm(FlaskForm): name = StringField('New Name', validators=[DataRequired()]) fields = {} fields['Field1'] = StringField('Field 1', validators=[DataRequired()]) fields['Field2'] = StringFi

我正在尝试使用字典中的表单字段填充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)
我的python代码与上面的代码类似。如果我尝试在jinja2中插入name字段,效果很好

{{ form.name.label(class="form-control-label form-control-sm") }}
但是,我不知道如何对字段字典中的字段执行相同的操作。如果我使用以下命令,它会给我一个错误。jinja2.exceptions.undeinderror:“wtforms.fields.core.UnboundField对象”没有属性“label”


是否可以像我尝试使用字典的方式使用它,或者如果我有大量字段,是否有其他选择。我使用dictionary的目标是使用jinja2循环来迭代dictionary元素以插入所有字段,而无需逐个键入。

您不能这样做。字段需要直接在表单本身中定义

但是你不需要。如果您只想在字段上迭代,您可以这样做,如所示。

Issue WTForms不支持在类级字典属性中定义字段。基类使用与元类相同的文件中的FormMeta来标识类定义中未绑定的WTForm字段,并将它们绑定到当前表单,这只会发现类级别的属性

解决方案 下面是一个使用表单工厂函数的简单示例

额外的表单字段作为lambda函数通过field_factory参数传入,因此我们可以将额外字段的创建延迟到name字段创建之后,尽管任何返回dict的可调用字段都可以工作。这是必需的,因为WTForms按创建顺序而不是按make_form函数内items dict中提供的顺序对字段进行排序

然后,您可以通过迭代表单而不是指定手动顺序来呈现它们

在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())


输出

<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">

不能在窗体外使用字段。你为什么要这么做?我不是在表单外使用它们。你为什么说我在表单外使用它?我不知道你是什么意思?那我就不懂你的密码了。表单是在哪里定义的,词典是从哪里来的?请显示完整视图。已编辑代码。这有用吗?好的。因此,这意味着我不能在forms.py中使用循环来创建迭代预定义键的字段,并将它们放入字典中,以便在jinja2中使用。谢谢。这看起来是解决这个问题的好办法。最后,我使用exec根据字典中存储的字段参数定义字段。然后我使用上面提到的@DanielRoseman方法对它们进行迭代,如图所示。
<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">