简体   繁体   English

使用字典插入WTForm字段。 jinja2.exceptions.UndefinedError:'wtforms.fields.core.UnboundField对象'没有属性'标签'

[英]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循环遍历字典元素以插入所有字段,而无需一个个地键入。

Issue 问题

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,这只会发现类级别的属性。

Solution

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.

相关问题 我该如何解决这个 Flask-WTF 问题:Jinja2.exceptions.UndefinedError: 'wtforms.fields.core.UnboundField object' has no attribute 'label' - How do i resolve this Flask-WTF issue: Jinja2.exceptions.UndefinedError: 'wtforms.fields.core.UnboundField object' has no attribute 'label' jinja2.exceptions.UndefinedError:对象没有属性 - jinja2.exceptions.UndefinedError: object has no attribute jinja2.exceptions.UndefinedError: 'dict object' 没有属性 'imageLinks' - jinja2.exceptions.UndefinedError: 'dict object' has no attribute 'imageLinks' Flask 自定义验证错误 - 类型错误:不支持的类型“<class 'wtforms.fields.core.UnboundField'> ” - Flask Custom Validation Error - TypeError: Unsupported type “<class 'wtforms.fields.core.UnboundField'>” Python Flask,错误“jinja2.exceptions.UndefinedError:‘str object’没有属性‘name’” - Python Flask, Error "jinja2.exceptions.UndefinedError: 'str object' has no attribute 'name'" jinja2.exceptions.UndefinedError: &#39;admin.forms.MyForm object&#39; 没有属性 &#39;hidden_​​tag&#39; - jinja2.exceptions.UndefinedError: 'admin.forms.MyForm object' has no attribute 'hidden_tag' jinja2.exceptions.UndefinedError: &#39;forms.ContactForm object&#39; 没有属性 &#39;message&#39; - jinja2.exceptions.UndefinedError: 'forms.ContactForm object' has no attribute 'message' 代码停止工作。 给我一个 `jinja2.exceptions.UndefinedError: &#39;list object&#39; has no attribute &#39;items&#39;` 错误 - Code stopped working. Gives me a `jinja2.exceptions.UndefinedError: 'list object' has no attribute 'items'` error airflow jinja2.exceptions.UndefinedError: 'airflow.models.taskinstance.TaskInstance object' 没有属性 'map_index' - airflow jinja2.exceptions.UndefinedError: 'airflow.models.taskinstance.TaskInstance object' has no attribute 'map_index' jinja2.exceptions.UndefinedError: '__main__.NamerForm object' 没有属性 'submit' - jinja2.exceptions.UndefinedError: '__main__.NamerForm object' has no attribute 'submit'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM