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

Flask-WTF FieldList生成条目数量多于预期问题排查

问题核心原因

  • 路由逻辑未区分请求方法:POST请求提交表单后,FlaskForm会自动从请求体中加载已提交的2行数据,你仍执行了追加行的逻辑,额外新增了2条空行,最终返回4条数据
  • 子表单的隐藏id字段未在前端渲染,也没有在初始化时赋值,导致提交后id为空
  • 路由返回模板时range参数依赖未定义的rows变量,存在语法错误
  • 前端模板末尾多了多余的<tr>标签,存在HTML结构错误

修复方案

1. 修正routes.py逻辑

仅在GET请求时初始化表单行,同时将数据库中的请求id填充到子表单的隐藏字段中:

@app.route("/home/admin", methods=['GET', 'POST'])
def home_admin():
    requests = RequestAccess.query.all()
    form = AccessForm()
    # 只有GET请求时初始化表单行,POST请求自动加载提交的数据
    if request.method == 'GET':
        for req in requests:
            # 填充隐藏id字段
            form.rows.append_entry(data={'id': req.id})

    if form.is_submitted():   
        print(form.data)

    if form.validate_on_submit():
        print('test')
        # 后续业务逻辑:遍历form.rows拿到审核结果操作数据库即可
        # for row in form.rows:
        #     req_id = row.id.data
        #     access_approved = (row.access.data == 'Yes')
        #     comment = row.comment.data
      #  return redirect(url_for('about'))
    print('rerender')
    # 修正range参数错误
    return render_template("admin_access_approval.html", title="Admin Access Approval", form=form, requests=requests, range=range(len(requests)))

2. 修正前端模板

渲染隐藏的id字段,删除多余的空<tr>标签:

{% extends "layout.html" %}
{% block content %}
<div id="example_wrapper-2" class="dataTables_wrapper" >
    <form id="basicForm" method="POST" action="" enctype="multipart/form-data">
        {{ form.hidden_tag() }}
        
        <h2 class="h3">Access requests Table</h2>  
        <table id="dataTableExample" class="table table-striped" style="width:100%"> 
            <caption class="sr-only">Employee List</caption>
            <thead>
                <tr><th scope="col">Name</th>
                        <th scope="col">Last name</th>
                        <th scope="col">Work Type</th>
                        <th scope="col">Email</th>
                        <th scope="col">Access</th>
                        <th scope="col">Comments</th>
                        <td></td>
                </tr>
            </thead>
            <tbody>
                {%for row, request, ii in zip(form.rows, requests,range)%}
                    <tr>
                        <!-- 渲染隐藏的id字段 -->
                        <td style="display:none;">{{ row.id() }}</td>
                        <td>{{request.name}}</td>
                        <td>{{request.lastname}}</td>
                        <td>{{request.workdesc}}</td>
                        <td>{{request.email}}</td>
                        <td>{{row.access(class="custom-select")}}</td>
                        <td>{{row.comment(class="form-control", value ='')}}</td>
                    </tr>
                {%endfor%}
            </tbody>
        </table>
        <div class="form-group">
            {{ form.submit(class="btn btn-primary mt-2", value = "Submit Changes") }}
        </div>
    </form>
</div>
{%endblock content%}

3. 可选优化forms.py

将已弃用的Required验证器替换为DataRequired:

class AccessForm(FlaskForm):
    rows = FieldList(FormField(AccessRow),validators=[DataRequired()])  
    submit = SubmitField('Update')

修复后效果

提交表单后form.rows只会返回和数据库中待审核请求数一致的条目,无多余空行,表单验证可正常通过,test打印语句可正常执行。

内容的提问来源于stack exchange,提问作者Manuel Sinco

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 06:48:03