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

Flask render_template未更新页面变量,思路是否有误?

问题根源

  1. 未处理AJAX响应:XMLHttpRequest仅发送了请求,但没有监听返回结果,也没有把新数据更新到页面DOM中,页面自然不会变化。
  2. 路由设计缺陷:用路径参数传递JSON字符串和逗号,会导致Flask路由解析异常(比如JSON里的引号、逗号会干扰路径匹配),且这种方式不符合常规规范。
  3. SQL参数错误:cs50的db.execute不需要将参数包裹在列表中,直接传值即可,多余的列表会导致参数绑定失败。
  4. 全局变量数据过期:db_names是全局变量,仅在Flask启动时查询一次数据库,后续数据库更新或筛选请求无法获取最新数据。

修复方案

核心调整点

  • 改用查询参数传递筛选值,避免路径参数的解析问题
  • 在AJAX中监听load事件,接收返回的JSON数据并手动更新页面DOM
  • 将数据库查询移到路由内部,确保每次请求都获取最新数据
  • 修正SQL查询的参数传递方式

修改后的代码

app.py

from cs50 import SQL
from flask import Flask, render_template, request, jsonify

app = Flask(__name__)
db = SQL("sqlite:///db/test.db")

@app.route("/", methods = ["POST", "GET"])
def index():
    """Show homepage with name list"""
    # 每次请求都查询最新数据
    db_names = db.execute("SELECT * FROM test ORDER BY id;")
    return render_template("index.html", names = db_names)

@app.route("/filter", methods = ["GET"])
def filter_names():
    """返回筛选后的结果,支持AJAX请求"""
    first_name = request.args.get('first_name')
    last_name = request.args.get('last_name')
    
    # 根据参数组合筛选逻辑
    if first_name and last_name:
        filtered_names = db.execute(
            "SELECT * FROM test WHERE first_name = ? OR last_name = ?;",
            first_name, last_name
        )
    elif first_name:
        filtered_names = db.execute("SELECT * FROM test WHERE first_name = ?;", first_name)
    elif last_name:
        filtered_names = db.execute("SELECT * FROM test WHERE last_name = ?;", last_name)
    else:
        filtered_names = db.execute("SELECT * FROM test ORDER BY id;")
    
    # 判断是否为AJAX请求,返回JSON数据
    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        return jsonify(filtered_names)
    return render_template("index.html", names = filtered_names)

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    </head>
    <body>
        <div class="main">
            <div>
                <button type="button" onclick="refresh()">Refresh</button>
            </div>
            <!-- 给列表容器加ID,方便后续更新DOM -->
            <main id="name-container">
                {% for name in names %}
                    {{ name.id }} {{ name.first_name }} {{ name.last_name }} <br>
                {% endfor %}
            </main>
        </div>
      </body>
      <!-- 使用Flask的url_for生成静态文件路径,避免相对路径问题 -->
      <script src="{{ url_for('static', filename='javascript.js') }}"></script>
</html>

javascript.js

function refresh() {
    var first_name = "Jehn"
    var last_name = "Wock"
    const request = new XMLHttpRequest();
    
    // 用URLSearchParams处理查询参数,避免手动拼接的编码问题
    const url = new URL(`${window.location.origin}/filter`);
    url.searchParams.append('first_name', first_name);
    url.searchParams.append('last_name', last_name);
    
    request.open("GET", url.toString());
    // 标记为AJAX请求,方便后端识别
    request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    
    // 监听请求完成事件,处理返回数据
    request.onload = function() {
        if (this.status >= 200 && this.status < 400) {
            const names = JSON.parse(this.responseText);
            const container = document.getElementById('name-container');
            // 清空原有内容
            container.innerHTML = '';
            // 遍历新数据,生成DOM元素并添加到容器
            names.forEach(name => {
                const line = document.createElement('div');
                line.textContent = `${name.id} ${name.first_name} ${name.last_name}`;
                container.appendChild(line);
            });
        }
    };
    
    request.send();
}

内容的提问来源于stack exchange,提问作者BananaJoe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:57:24