如何使用flask-wtf渲染动态表单

问题描述 投票:0回答:1

我正在尝试使用flask-wtf(WTForms)渲染动态表单,它将具有以下动态数据/输出。

  1. 盒子列表(n 件)
  2. 选择元素(目标集合,m 个选择,重复每行)
  3. 每行的复选框(如果应传输)
盒子名称 盒子说明 盒子位置 目标集合 转让?
盒子1 描述1 附件 重复选择字段并选择相同的选项 [ ] - 复选框
方框2 描述2 附件 重复选择字段并选择相同的选项 [ ] - 复选框
方框3 描述 3 附件 重复选择字段并选择相同的选项 [ ] - 复选框
... ... ... 重复选择字段并选择相同的选项 [ ] - 复选框
class MultiCheckboxField(SelectMultipleField):
    widget = ListWidget(prefix_label=False)
    option_widget = CheckboxInput()

class FindingAidsOptions(FlaskForm):
    finding_aid_choices = SelectField("", coerce=int, validators=[DataRequired()])


class FindingAidTransferForm(FlaskForm):
    target_findingaid = FieldList(FormField(FindingAidsOptions), min_entries=1, max_entries=5)
    physicalobjects = MultiCheckboxField('Label',coerce=int)
    submit = SubmitField('Transfer Selected Objects')

烧瓶路线

    form = forms.FindingAidTransferForm()

    form.target_findingaid.choices = findingaid_choices #This does not seem to work, as I never can iterate over the values below
    form.physicalobjects.choices = physical_objects # this works, and can iterate over it

    return render_template(
        "atom-migrate-physical-object-listing.jinja2",
        title="Accessions Phyiscal Object Migrations",
        template="atom-caia-template",
        atom_records=accession_record,
        findingaids_physical_objects=findingaids_physical_objects,
        form=form
    )
# Example values for the choice data

findingaid_choices = [(26958, 'Records Choice 1'), (142451, 'Records Choice 2')]
physical_objects = [(107267, 'Box 5, TOM'), (130235, 'Box 1, A83412001377'), (139827, 'Box 2, A83411997169')]

示例模板。

<form class="form" method="post" role="form">
    {{ form.hidden_tag() }}
    <table class="table table-striped table-sm table-responsive">
        <thead>
            <th>Object Name</th>
            <th>Description</th>
            <th>Location</th>
            <th>Destination Finding Aid</th>
            <th>Transfer to Findingaid?</th>
        </thead>
        <tbody>
            {% for po in form.physicalobjects %}
            <tr>
                <td>{{ findingaids_physical_objects[po.data]['physical_object_name'] if findingaids_physical_objects[po.data]['physical_object_name'] is not none }}</td>
                <td>{{ findingaids_physical_objects[po.data]['physical_object_desc'] if findingaids_physical_objects[po.data]['physical_object_desc'] is not none }}</td>
                <td>{{ findingaids_physical_objects[po.data]['physical_object_loc'] if findingaids_physical_objects[po.data]['physical_object_loc'] is not none }}</td>
                <td>Select Box with finding_aid_choices goes here</td>
                <td>Check box if it should be transferred from physicalobjects</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

        {% for item in form.target_findingaid %}
         <pre>{{ item.id }}</pre>
         {# This only seems to output target_findingaid-0, even though I have multiple. If I change the min_entries I do get an incremented value.
        {% endfor %}
        
        {{ formTextInput(form.submit) }}
</form>
flask flask-wtforms wtforms
1个回答
0
投票

我昨晚终于弄清楚了。我必须移动一些部分,但下面是我最终必须做的事情才能使其正常工作。

形成班级:

class PhysicalObjects(Form):
    box_id = HiddenField('Physical Object ID')
    name = StringField('Name')
    location = StringField('Location')
    transfer = BooleanField('Transfer Object')
    target_findingaid = SelectField("Target Findingaid", validators=[DataRequired()],coerce=int)

class FindingAidTransferForm(FlaskForm):
    physicalobjects = FieldList(FormField(PhysicalObjects), min_entries=1)
    submit = SubmitField('Transfer Selected Objects')

循环模板

            {% for po in form.physicalobjects.entries %}
            <tr>{{po.form.box_id }}
                <td>{{ po.form.name.data if po.form.name.data is not none }}</td>
                <td>{{ po.form.location.data if po.form.location.data is not none }}</td>
                <td>{{ po.form.target_findingaid }}</td>
                <td>{{ po.form.transfer() }}</td>
            </tr>
            {% endfor %}

路线代码

    findingaid_choices = []
    physical_objects = []
    phys_objects_group = namedtuple("Physical_Objects", ['box_id', 'name', 'location'])
    for _, rec in findingaids_physical_objects.items():
        if rec['related_item_type'] == "findingaid":
            findingaid_choices.append((rec['related_item_id'], rec['findingaid_title']))
        else: 
            physical_objects.append(phys_objects_group(
                rec['related_item_id'],
                rec['physical_object_name'],
                rec['physical_object_loc']
            ))

    data = {'physicalobjects':  physical_objects}
    form = forms.FindingAidTransferForm(data=data)

    for entry in form.physicalobjects.entries:
        entry.target_findingaid.choices = findingaid_choices

    if form.validate_on_submit():

        ... do stuff

    else:
        return render_template(
            "atom-migrate-physical-object-listing.jinja2",
            title="Accessions Physical Object Migrations",
            template="atom-caia-template",
            atom_records=accession_record,
            findingaids_physical_objects=findingaids_physical_objects,
            form=form
        )
© www.soinside.com 2019 - 2024. All rights reserved.