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
相关产品推荐
相关产品推荐

