Flask-WTF动态生成可变数量表单/单按钮提交多表单问题咨询
代码调整实现方案
1. 后端代码修改
新增轻量SQLite持久化逻辑,同时调整提交接口适配动态表单的参数接收,修改后的代码如下:
from flask import Flask, render_template, url_for, redirect, request from flask_wtf import FlaskForm from wtforms import StringField, PasswordField, SubmitField, DateField, TextAreaField from wtforms.validators import DataRequired, Email from flask_bootstrap import Bootstrap from WO_Gatherer import WoHandler import sqlite3 from datetime import datetime # 初始化数据库,仅首次运行执行 def init_db(): conn = sqlite3.connect('wo_data.db') c = conn.cursor() c.execute('''CREATE TABLE IF NOT EXISTS wo_submissions (id INTEGER PRIMARY KEY AUTOINCREMENT, wo_number TEXT NOT NULL, available_date DATE, comment TEXT, submit_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP)''') conn.commit() conn.close() work_orders = WoHandler() liquids_jobs, ss_jobs, line_116_jobs,lyo_jobs = work_orders.room_and_department() login_key = '1234' class MyForm(FlaskForm): email = StringField(label='Email', validators=[DataRequired(), Email()]) password = PasswordField(label='Login Key', validators=[DataRequired()]) submit = SubmitField(label='Log In') class PmcForm(FlaskForm): date = DateField(label='Date') comment = TextAreaField(label='Comment') submit = SubmitField(label='Submit') app = Flask(__name__) Bootstrap(app) app.secret_key = "some-secret-string" init_db() # 初始化数据库 @app.route('/', methods=['GET']) def home(): login_form = MyForm() return render_template('index.html', form=login_form) @app.route('/<department>', methods=['POST']) def pmc(department): global login_key, liquids_jobs, ss_jobs, line_116_jobs, lyo_jobs form = PmcForm() job_map = { 'liquids': liquids_jobs, 'SS': ss_jobs, 'L116': line_116_jobs, 'Lyo': lyo_jobs } job_packet = job_map.get(department, []) data = { 'email': request.form['email'], 'key': request.form['password'] } if data['key'] == login_key: return render_template(f'{department}.html', jobs=job_packet, form=form, department=department) else: return '<h1>Incorrect Login Key</h1>' @app.route('/success', methods=['POST']) def success(): conn = sqlite3.connect('wo_data.db') c = conn.cursor() submit_data = [] # 遍历所有提交的参数,按工单ID分组 for key, value in request.form.items(): if key.startswith('date_'): wo_number = key.split('_')[1] comment = request.form.get(f'comment_{wo_number}', '') c.execute("INSERT INTO wo_submissions (wo_number, available_date, comment) VALUES (?, ?, ?)", (wo_number, value, comment)) submit_data.append({"wo_number": wo_number, "date": value, "comment": comment}) conn.commit() conn.close() # 此处可新增SMTP发邮件逻辑,直接将数据发送给计划员 return f'<h1>Response successfully submitted! Thank you. {str(submit_data)}</h1>' if __name__ == '__main__': app.run(debug=True)
2. PMC公共模板修改
将表单标签包裹整个表格,让所有工单的输入项都属于同一个表单,实现单个按钮提交所有数据:
{% include 'header.html' %} <section class='header {% block color %}{% endblock %}'> <img class="card-img-top header-icon" src="static/images/{% block image %}{% endblock %}.svg" alt="Card image cap"> <h1 class="header-text">{% block title %}{% endblock %} Production Maintenance Coordination</h1> </section> <section class='pmc-table'> <!-- 把form标签移到此处,包裹整个表格 --> <form action="{{ url_for('success') }}" method="POST"> <table class="table"> <thead class="thead-dark"> <tr> <th scope="col">WO Number</th> <th scope="col">Description</th> <th scope="col">Rooms</th> <th scope="col">Impact</th> <th scope="col">Est Comp Time</th> <th scope="col">Input Form</th> </tr> </thead> <tbody> {% block content %}{% endblock %} </tbody> </table> <div class="submit-button"> {% block button %}{% endblock %} </div> </form> </section> {% include 'footer.html' %}
3. 液体部门页面模板修改
给每个工单的输入字段添加唯一的工单ID作为后缀,让后端可以区分不同工单的提交数据:
{% extends 'pmc.html' %} {% block color %}blue{% endblock %} {% block image %}liquids{% endblock %} {% block title %}Liquids{% endblock %} {% block content %} {% for job in jobs %} <tr> <th scope="row">{{ job[0] }}</th> <td>{{ job[1] }}</td> <td>{% for room in job[5] %}{{ room + '\n'}}{% endfor %}</td> <td>{{ job[2] }}</td> <td>{{ job[3] }}</td> <td>Date: <br> <!-- 给字段name加工单ID后缀,实现唯一标识 --> <input type="date" name="date_{{ job[0] }}" id="date_{{ job[0] }}"> <br> Comments: <br> <textarea name="comment_{{ job[0] }}" id="comment_{{ job[0] }}"></textarea> </td> </tr> {% endfor %} {% endblock %} {% block button %}<button type="submit">提交所有工单</button>{% endblock %}
补充说明
其他部门的模板只需要参照液体部门的模板调整字段命名规则即可直接复用,若需要替换持久化方案,直接修改success接口的数据库写入逻辑即可适配MySQL、PostgreSQL等其他数据库。
内容的提问来源于stack exchange,提问作者Anthony Del Russo
相关产品推荐
相关产品推荐

