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

基于Flask+psycopg2的无刷新支付数据模态框实现问询

问题解决与完整流程实现

一、修复模板加载报错

报错根源是application_modal.html中注释的代码仍被Jinja2解析,而你未在Flask路由中传递data变量,导致data为Undefined类型无法序列化。

修复步骤:

  1. 清理模板代码
    删除或用Jinja注释语法包裹模板中引用未定义变量的代码(避免Jinja解析):
{# 注释掉不需要的代码,Jinja不会解析内部变量 #}
{# var data = JSON.parse('{{ data | tojson | safe }}'); #}
  1. 优化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">&times;</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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:05:54