簡體   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'

我正在嘗試使用字典中的表單字段填充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") }}

但是,我不知道如何對fields字典中的fields執行相同的操作。 如果使用以下命令,則會給我一個錯誤。( jinja2.exceptions.UndefinedError: 'wtforms.fields.core.UnboundField object' has no attribute 'label'

{{ form.fields['Field1'].label(class="form-control-label form-control-sm") }}

是否可以按照我嘗試使用字典的方式使用字典,或者如果我有大量字段,是否可以使用字典? 我使用字典的目標是使用jinja2循環遍歷字典元素以插入所有字段,而無需一個個地鍵入。

問題

WTForms不支持在類級別的字典屬性中定義字段。 Form基類使用FormMeta(來自同一文件)作為元類,以在類定義中標識未綁定的WTForm字段並將其綁定到當前Form,這只會發現類級別的屬性。

下面是使用表單工廠功能的最小工作示例。

額外的表單字段通過field_factory參數作為lambda函數傳入,以便我們可以將額外字段的創建延遲到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">

你做不到 字段需要直接在表單本身中定義。

但是您不需要。 如果只想遍歷字段,則可以執行此操作,如WTForms docs中所示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM