Колба WTForms BooleanField UnboundField - PullRequest
       11

Колба WTForms BooleanField UnboundField

0 голосов
/ 16 ноября 2018

Я пишу скрипт, который обычно извлекает 5 строк из базы данных, и я хочу отобразить его в виде списка флажков.

Но он не отображается правильно: он говорит "UnboundField"

form.py

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

rout.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>

Результат:

rendered table

1 Ответ

0 голосов
/ 16 ноября 2018

Вы поместили свои поля во вложенный словарь.Форма не может связывать такие поля, так как она не может обрабатывать произвольные контейнеры.

Вместо этого вам нужно поместить поля в вложение поля .Я бы использовал FormField() поле , чтобы указать на вложенный класс Form.Вы можете сгенерировать вложенный класс Form, вызвав конструктор BaseForm() :

То, что предоставляет BaseForm , является контейнером для коллекции полей,, который он будет связывать при создании экземпляра и держать во внутреннем диктате.Доступ в стиле Dict к экземпляру BaseForm позволит вам получить доступ (и изменить) вложенные поля.

Затем, когда вы создадите экземпляр вашего ExampleForm() класса, он будет связывать FormField поле, которое, в свою очередь, создает экземпляр вложенного объекта формы, который затем связывает каждое из полей, которые вы дали BaseForm()

, так как вызов BaseForm(fields) создаст форму экземпляр , вам нужно сначала обернуть это в функцию, прежде чем использовать ее как вложенную форму:

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

При переборе поля list_checkbox при рендеринге вы получаете поля напрямую и получаетеметка из объекта поля:

<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 такой же):

>>> 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() затемтакже убедитесь, что вы можете установить DefЗначения Ault для вашей формы или доступ к набору данных при повторной публикации формы:

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