You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask FieldList无法接收前端修改数据及validate_on_submit报错问题

错误原因

  1. 手动修改字段名不符合WTForms FieldList的命名规则,提交的表单数据无法被正确解析,只能拿到初始化时的默认值,布尔字段匹配不到提交值就会始终返回False。
  2. 直接将自定义的表单列表赋值给entry_form_list属性,覆盖了原有的FieldList实例,导致调用校验方法时缺少内部所需的copy等方法,抛出AttributeError。

修复方案

1. 调整表单类

将id字段改为隐藏字段,符合业务逻辑不需要前端显式输入:

class Beneficiary_Migration_Entry_Form(FlaskForm):
    id = HiddenField('')
    name = StringField('')
    school = SelectField('', validate_choice=False)
    student_class = SelectField('', validate_choice=False)
    migrate = BooleanField('')
class Beneficiary_Migration_Form(FlaskForm):
    entry_form_list = FieldList(FormField(Beneficiary_Migration_Entry_Form))
    submit = SubmitField('Submit')

2. 重写路由逻辑

不要手动修改字段名、不要直接覆盖FieldList属性,用WTForms内置的append_entry方法填充动态条目,区分GET/POST请求的表单初始化逻辑:

@app.route('/migration/student/<school_year_id>', methods=['GET', 'POST'])
@login_required
def student_migration_page(school_year_id):
    school_year_id = int(school_year_id)
    school_year = School_Year.query.filter(School_Year.id==school_year_id).first()
    school_choices = get_school_list()
    entries = Student.query.filter(Student.user_id==current_user.id).all()
    school_map = Database_Manager.get_schools_map(current_user)

    # 初始化表单,POST请求会自动加载提交的数据
    migration_form = Beneficiary_Migration_Form()

    if migration_form.validate_on_submit():
        # 直接遍历即可拿到修改后的所有数据
        for form_entry in migration_form.entry_form_list:
            print(form_entry.id.data, form_entry.migrate.data)
        return redirect(url_for('migration_page', school_year_id=school_year_id))
    
    # GET请求才用数据库数据填充表单
    for entry in entries:
        migration_form.entry_form_list.append_entry(
            data={
                "id": entry.id,
                "name": entry.name
            }
        )
        # 给当前条目的选择字段设置选项
        entry_form = migration_form.entry_form_list[-1]
        entry_form.school.choices = school_choices
        entry_form.student_class.choices = [('','')]

    return render_template('migration-elev.html', school_map=school_map,school_year=school_year, migration_form=migration_form)

3. 调整前端代码

去掉每个条目的重复hidden_tag(),避免CSRF token冲突:

<form action="" method="post">
    {{ migration_form.hidden_tag() }}
    <table class="table table-striped table-dark" style="text-align: center;">
        <thead class="thead-dark">
            <tr>
            <th scope="col">ID</th>
            <th scope="col">Nume</th>
            <th scope="col">Scoala</th>
            <th scope="col">Clasa/ Grupa</th>
            <th scope="col">Transfer</th>
            </tr>
        </thead>
        <tbody>
            {% for form in migration_form.entry_form_list %}
            <tr>
                    <td>{{form.id.data}}</td>
                    <td>{{form.name}}</td>
                    <td>{{form.school}}</td>
                    <td>{{form.student_class}}</td>
                    <td>{{form.migrate}}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
    <p>{{ migration_form.submit(class_="btn btn-primary") }}</p>
</form>

内容的提问来源于stack exchange,提问作者Robert-Nicolae Solca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 01:51:04