Flask render_template未更新页面变量,思路是否有误?
问题根源
- 未处理AJAX响应:XMLHttpRequest仅发送了请求,但没有监听返回结果,也没有把新数据更新到页面DOM中,页面自然不会变化。
- 路由设计缺陷:用路径参数传递JSON字符串和逗号,会导致Flask路由解析异常(比如JSON里的引号、逗号会干扰路径匹配),且这种方式不符合常规规范。
- SQL参数错误:cs50的
db.execute不需要将参数包裹在列表中,直接传值即可,多余的列表会导致参数绑定失败。 - 全局变量数据过期:
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
相关产品推荐
相关产品推荐

