Django模板切换失效求助:POST请求后无法切换至layout.html
问题根源
- 你用
fetch发起的是AJAX异步请求,这种请求只会在后台悄悄接收服务器返回的内容,不会自动替换当前页面或触发跳转。所以后端返回的layout.html模板内容压根没渲染到浏览器页面上。 - 另外
layout.html里写的是{{ quiz }}变量,但后端视图传的是string和result,就算成功渲染,页面也会显示空值。
两种修复方案
方案一:改用普通表单提交(不用AJAX)
直接用表单包裹按钮,通过提交表单触发页面跳转,逻辑更简单:
修改index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> {% load static %} <link rel="stylesheet" href="{% static 'css/style.css' %}"> <title>Math Quiz</title> </head> <body> <p class="title">Math Quiz</p> <div class="box"> <form method="POST"> {% csrf_token %} <button type="submit" name="level" value="1">Level 1</button><br><br> <button type="submit" name="level" value="2">Level 2</button><br><br> <button type="submit" name="level" value="3">Level 3</button> </form> </div> </body> </html>
修改views.py,从POST表单数据里取等级:
from django.shortcuts import render import random def appView(request): if request.method == "POST": num = request.POST.get('level', 1) return _quiz(request, int(num)) return render(request,"index.html") def _quiz(request,lvl=1): operation = ["+", "-", "/", "*"] string = str(random.randint(0,100)) +" "+ str(operation[random.randint(0,3)]) + " " + str(random.randint(1,10*lvl)) result = eval(string) string += " = " # 把变量名改成和layout.html里的{{ quiz }}对应 return render(request, "layout.html", {"quiz": string, "result": result})
修正layout.html(如果要显示结果可以加上):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> {% load static %} <link rel="stylesheet" href="{% static 'css/style.css' %}"> <title>Math Quiz</title> </head> <body> <p class="title">Math Quiz2</p> <div class="box"> <p>{{ quiz }}</p> <!-- 可选:显示答案 --> <!-- <p>答案:{{ result }}</p> --> </div> </body> </html>
方案二:保留AJAX,处理fetch响应
如果想要异步不刷新的体验,就在fetch里加逻辑,把返回的HTML替换当前页面:
修改index.html里的脚本:
<script> function lvl(num) { fetch("",{ method: "POST", headers: { 'Content-Type': 'application/json', 'X-CSRFToken': '{{ csrf_token }}' }, body: JSON.stringify({ "num": num }) }) .then(response => response.text()) .then(html => { // 替换整个页面的HTML内容 document.documentElement.innerHTML = html; }) .catch(error => console.error('出错了:', error)); }; </script>
同样要修正views.py里的变量名,和layout.html的{{ quiz }}对应,参考方案一的_quiz函数即可。
额外提醒
- 用
eval()计算表达式有安全风险,如果是公开项目,建议换成simpleeval这类安全的表达式计算库。 - 确保Django的URL配置正确,
appView对应的URL能正常接收POST请求。
内容的提问来源于stack exchange,提问作者MrLiu
相关产品推荐
相关产品推荐

