基于Flask+psycopg2的无刷新支付数据模态框实现问询
问题解决与完整流程实现
一、修复模板加载报错
报错根源是application_modal.html中注释的代码仍被Jinja2解析,而你未在Flask路由中传递data变量,导致data为Undefined类型无法序列化。
修复步骤:
- 清理模板代码
删除或用Jinja注释语法包裹模板中引用未定义变量的代码(避免Jinja解析):
{# 注释掉不需要的代码,Jinja不会解析内部变量 #} {# var data = JSON.parse('{{ data | tojson | safe }}'); #}
- 优化Flask路由
无需用json.dumps包裹渲染后的模板字符串,直接返回即可:
@payment_app_bp.route('/open_modal/<int:payment_id>', methods=['GET']) def open_modal(payment_id): # 后续将补充数据库查询逻辑,先传递空数据修复报错 modal_content = render_template('application_modal.html') return jsonify(modal_content=modal_content)
二、完整流程实现
1. 前端:点击支付名称触发模态框
支付列表HTML结构
<table> <thead> <tr><th>支付名称</th><th>金额</th><th>状态</th></tr> </thead> <tbody> {% for payment in payments %} <tr> <td><a href="javascript:void(0)" class="payment-name" data-id="{{ payment.id }}">{{ payment.name }}</a></td> <td>{{ payment.amount }}</td> <td>{{ payment.status }}</td> </tr> {% endfor %} </tbody> </table> <!-- 提前创建模态框容器,避免重复生成DOM --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">编辑支付信息</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body" id="modalContent"> <!-- 动态加载的表单内容将插入此处 --> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="savePayment">保存修改</button> </div> </div> </div> </div>
前端交互脚本
$(document).ready(function() { // 点击支付名称加载对应模态框 $('.payment-name').click(function() { const paymentId = $(this).data('id'); $.ajax({ url: `/open_modal/${paymentId}`, type: 'GET', success: function(response) { $('#modalContent').html(response.modal_content); $('#myModal').modal('show'); // 给保存按钮绑定当前支付ID $('#savePayment').data('id', paymentId); }, error: function() { alert('加载模态框失败,请重试'); } }); }); // 保存修改的无刷新请求 $('#savePayment').click(function() { const paymentId = $(this).data('id'); // 收集表单数据 const formData = { name: $('#paymentName').val(), amount: $('#paymentAmount').val(), status: $('#paymentStatus').val() }; $.ajax({ url: `/update_payment/${paymentId}`, type: 'POST', contentType: 'application/json', data: JSON.stringify(formData), success: function(response) { if (response.success) { $('#myModal').modal('hide'); // 局部刷新支付列表对应行 $(`.payment-name[data-id="${paymentId}"]`).text(formData.name); alert('修改保存成功'); } else { alert('保存失败:' + response.message); } }, error: function() { alert('请求失败,请检查网络连接'); } }); }); });
2. Flask后端:数据库交互与模板渲染
数据库连接与查询逻辑
import psycopg2 from psycopg2.extras import DictCursor from flask import render_template, jsonify, request # 封装数据库连接工具函数 def get_db_connection(): conn = psycopg2.connect( host='你的数据库地址', database='你的数据库名', user='数据库用户名', password='数据库密码' ) return conn # 获取支付数据并渲染模态框模板 @payment_app_bp.route('/open_modal/<int:payment_id>', methods=['GET']) def open_modal(payment_id): conn = get_db_connection() cur = conn.cursor(cursor_factory=DictCursor) cur.execute('SELECT * FROM payments WHERE id = %s', (payment_id,)) payment = cur.fetchone() cur.close() conn.close() if not payment: return jsonify(error='支付记录不存在'), 404 # 将查询到的支付数据传递给模板 modal_content = render_template('application_modal.html', payment=payment) return jsonify(modal_content=modal_content) # 处理支付信息更新请求 @payment_app_bp.route('/update_payment/<int:payment_id>', methods=['POST']) def update_payment(payment_id): data = request.get_json() if not data: return jsonify(success=False, message='无提交数据'), 400 conn = get_db_connection() cur = conn.cursor() try: cur.execute(''' UPDATE payments SET name = %s, amount = %s, status = %s WHERE id = %s ''', (data['name'], data['amount'], data['status'], payment_id)) conn.commit() return jsonify(success=True) except Exception as e: conn.rollback() return jsonify(success=False, message=str(e)), 500 finally: cur.close() conn.close()
3. 模态框表单模板(application_modal.html)
生成带初始数据的可编辑表单:
<form id="paymentForm"> <div class="form-group"> <label for="paymentName">支付名称</label> <input type="text" class="form-control" id="paymentName" value="{{ payment.name }}"> </div> <div class="form-group"> <label for="paymentAmount">金额</label> <input type="number" class="form-control" id="paymentAmount" value="{{ payment.amount }}" step="0.01"> </div> <div class="form-group"> <label for="paymentStatus">状态</label> <select class="form-control" id="paymentStatus"> <option value="pending" {% if payment.status == 'pending' %}selected{% endif %}>待支付</option> <option value="completed" {% if payment.status == 'completed' %}selected{% endif %}>已完成</option> <option value="failed" {% if payment.status == 'failed' %}selected{% endif %}>支付失败</option> </select> </div> </form>
三、关键注意事项
- 数据库操作需添加事务处理,更新失败时执行回滚,避免数据不一致。
- 前端提交数据时需指定
contentType: 'application/json',后端用request.get_json()接收。 - 局部刷新支付列表可提升用户体验,无需重载整个页面。
内容的提问来源于stack exchange,提问作者dutik
相关产品推荐
相关产品推荐

