Flask WTForms BooleanField UnboundField [英] Flask WTForms BooleanField UnboundField

查看:138
本文介绍了Flask WTForms BooleanField UnboundField的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个脚本,该脚本通常从数据库中检索5行,并且希望将其显示为复选框列表.

I am writing a script that normally retrieves 5 lines from the database and I want to display it as a checkbox list.

但是它无法正确显示:显示为"UnboundField"

But it doesn't display correctly: it says " UnboundField "

form.py

class ExampleForm(FlaskForm):
    [...query & results...]
    for line in results_sql:
        list_checkbox[line.label] = BooleanField(line.label)

routes.py

@bp.route('/example')
def example():
    form = ExampleForm()
    return render_template("index.html", form=form)

index.html

<table class="table table-bordered table-condensed">
    {% for checkbox in form.list_checkbox %}
    <tr>
        <td>{{ checkbox }}</td>
        <td>{{ form.list_checkbox[checkbox ] }}</td>
    </tr>
    {% endfor %}
</table>

结果:

推荐答案

您已将字段放入嵌套字典中.表单无法处理任意容器,因此无法绑定此类字段.

You've put your fields inside a nested dictionary. The form can't bind such fields as it can't handle arbitrary containers.

相反,您需要将字段放在字段附件中.我会使用 FormField()字段指向嵌套的 Form 类.您可以通过调用

Instead, you need to put the fields in a field enclosure. I'd use a FormField() field to point to a nested Form class. You can generate the nested Form class by calling the BaseForm() constructor:

BaseForm 提供的是用于存储字段的容器,它将在实例化时绑定,并保存在内部字典中.通过对BaseForm实例的Dict样式访问,您可以访问(和修改)封闭的字段.

What BaseForm provides is a container for a collection of fields, which it will bind at instantiation, and hold in an internal dict. Dict-style access on a BaseForm instance will allow you to access (and modify) the enclosed fields.

然后,当您创建 ExampleForm()类的实例时,它将绑定 FormField 字段,然后依次创建嵌套表单的实例对象,然后绑定您给 BaseForm()

Then, when you create an instance of your ExampleForm() class, it'll bind the FormField field, which then in turn creates an instance of the nested form object, which then binds each of the fields you gave BaseForm()

由于调用 BaseForm(fields)将创建一个表单 instance ,因此您确实需要先将其包装在函数中,然后才能将其用作嵌套表单:

Because calling BaseForm(fields) will create a form instance, you do need to wrap that in a function first before you can use it as a nested form:

def form_from_fields(fields):
    def create_form(prefix='', **kwargs):
        form = BaseForm(fields, prefix=prefix, meta=FlaskForm.Meta)
        form.process(**kwargs)
        return form
    return create_form

class ExampleForm(FlaskForm):
    # ...

    list_checkbox = FormField(
        form_from_fields(
            [(line.label, BooleanField(line.label)) for line in results_sql]
        )
    )

BaseForm()不会像 Form 类那样获取任何数据,因此您需要传递 FormField()的参数.在返回实例之前,先将其传递给 .process()方法的创建实例.

BaseForm() doesn't take any data like a Form class would, so you need to pass the parameters that FormField() passes into create an instance to the .process() method before returning the instance.

在渲染时遍历 list_checkbox 字段时,直接获取字段,并从字段对象获取标签:

When iterating over the list_checkbox field when rendering, you get the fields directly and you get the label from the field object:

<table class="table table-bordered table-condensed">
    {% for checkbox in form.list_checkbox %}
    <tr>
        <td>{{ checkbox.label }}</td>
        <td>{{ checkbox }}</td>
    </tr>
    {% endfor %}
</table>

演示(使用基本的WTForms库,但是Flask-WTF过程相同)

Demo (using the base WTForms library, but the Flask-WTF process is the same):

>>> from wtforms.form import BaseForm, Form
>>> from wtforms.fields import BooleanField, FormField
>>> fields = ['Calendrier', 'Commentaire', 'Dessin', 'Ex-libris', 'Gravure']
>>> def form_from_fields(fields):
...     def create_form(prefix='', **kwargs):
...         form = BaseForm(fields, prefix=prefix)
...         form.process(**kwargs)
...         return form
...     return create_form
...
>>> class ExampleForm(Form):
...     list_checkbox = FormField(form_from_fields([(field, BooleanField(field)) for field in fields]))
...
>>> form = ExampleForm()
>>> form.list_checkbox
<wtforms.fields.core.FormField object at 0x1232a76d8>
>>> list(form.list_checkbox)
[<wtforms.fields.core.BooleanField object at 0x1232a77f0>, <wtforms.fields.core.BooleanField object at 0x1232a78d0>, <wtforms.fields.core.BooleanField object at 0x1232a7978>, <wtforms.fields.core.BooleanField object at 0x1232a7a20>, <wtforms.fields.core.BooleanField object at 0x1232a7ac8>]
>>> print(*form.list_checkbox, sep='\n')
<input id="list_checkbox-Calendrier" name="list_checkbox-Calendrier" type="checkbox" value="y">
<input id="list_checkbox-Commentaire" name="list_checkbox-Commentaire" type="checkbox" value="y">
<input id="list_checkbox-Dessin" name="list_checkbox-Dessin" type="checkbox" value="y">
<input id="list_checkbox-Ex-libris" name="list_checkbox-Ex-libris" type="checkbox" value="y">
<input id="list_checkbox-Gravure" name="list_checkbox-Gravure" type="checkbox" value="y">

FormField()字段还可以确保您可以为表单设置默认值,或者可以确保在再次发布表单时可以访问数据集:

The FormField() field then also makes sure that you can set default values for your form, or that you can then access the data set when the form is posted again:

>>> form = ExampleForm(list_checkbox={'Calendrier': True})
>>> print(form.list_checkbox['Calendrier'])
<input checked id="list_checkbox-Calendrier" name="list_checkbox-Calendrier" type="checkbox" value="y">
>>> print(form.list_checkbox['Commentaire'])
<input id="list_checkbox-Commentaire" name="list_checkbox-Commentaire" type="checkbox" value="y">

这篇关于Flask WTForms BooleanField UnboundField的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆