HTML表单向Flask提交异常:始终发送首行数据问题排查
问题原因分析
1. 表单DOM结构无效
你在循环生成任务行时,错误地在第一个任务行的<td>内提前闭合了</form>标签,导致后续所有任务行都脱离了表单范围。浏览器解析这种错误DOM时,仅会将第一行内容纳入表单,后续行的提交按钮点击时,实际提交的仍是这个不完整的表单,因此只会发送第一行的数据。
2. 重复的name属性导致ID值错误
所有任务行的ID输入框name都设置为id,没有区分不同任务的ID。当表单提交时,多个同名输入框只会传递第一个输入框的值,后端拿到的task_id永远是第一行任务的ID,最终只会更新第一行数据。
修复方案
修复HTML结构
将每个任务行封装为独立的表单,确保每行提交按钮仅提交当前行的数据:
<table> <thead> <tr> <th contenteditable="false">ID</th> <th contenteditable="false">Title</th> <th contenteditable="false">Description</th> <th contenteditable="false">Status</th> <th contenteditable="false">Deadline</th> <th contenteditable="false">Due Date</th> <th contenteditable="false">Task Type</th> <th contenteditable="false">Update</th> </tr> </thead> <tbody> {% for task in data %} <tr> <form action="/tasks" method="POST"> <td><input type="text" name="id" class="form-control" value="{{ task.id }}" readonly></td> <td><input class="form-control" type="text" name="title" value="{{ task.title }}"></td> <td><input class="form-control" type="text" name="description" value="{{ task.description }}"></td> <td><input class="form-control" name="status" value="{{ task.status }}" readonly></td> <td><input class="form-control" type="text" name="creation_time" value="{{ task.creation_time }}"></td> <td><input class="form-control" type="text" name="deadline" value="{{ task.deadline }}"></td> <td><input class="form-control" type="text" name="task_type" value="{{ task.task_type }}"></td> <td><button type="submit">Update Row</button></td> </form> </tr> {% endfor %} </tbody> </table>
修复Flask后端代码
- 直接从表单获取当前行的任务ID和字段值
- 必须替换字符串拼接SQL的写法,改用参数化查询避免SQL注入风险:
task_id = request.form.get("id") title = request.form.get("title") description = request.form.get("description") status = request.form.get("status") creation_time = request.form.get("creation_time") deadline = request.form.get("deadline") task_type = request.form.get("task_type") ses_id = session['userid'] # 参数化查询,避免SQL注入 query = """ UPDATE Task SET title=%s, description=%s, status=%s, deadline=%s, creation_time=%s, user_id=%s, task_type=%s WHERE id=%s; """ cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor) cursor.execute(query, (title, description, status, deadline, creation_time, ses_id, task_type, task_id)) mysql.connection.commit()
内容的提问来源于stack exchange,提问作者asimtot
相关产品推荐
相关产品推荐

