【发布时间】:2022-01-21 01:11:22
【问题描述】:
我面临的问题与基于由 jQuery 发起的 AJAX 发布请求更新的上下文重新渲染 Django 视图有关。我之所以需要 AJAX 请求,是因为我需要在不刷新页面的情况下修改页面 UI,这对我要构建的内容至关重要。
到目前为止,我能够触发 AJAX 发布请求到应该发生更新的同一页面的 URL,并且 Django view.py 充分注册它已被调用。 然而,虽然我可以重现更新 Django 视图上下文的能力,但该视图似乎并没有根据更新的上下文重新呈现更新的 HTML。
How to re-render django template code on AJAX call 的帖子似乎准确地描述了我的问题。该线程投票最多的解决方案是有一个仅在仅呈现部分模板(不是完整的 HTML 页面)的 AJAX 调用的情况下触发的条件 - 对应于的部分模板要更新的组件。这是在下面的代码 sn-ps 中重现的内容,但 HTML 不会根据更新的上下文而更改。
附件是相关代码sn-ps,用于简单尝试,页面默认显示<h1>2<h1/>,当我们单击窗口上的任意位置时,它意味着更新为5。单击窗口上的任意位置会触发 AJAX 调用,但页面不会更新为 <h1>5<h1/>。
view.py
def index(request):
context = {"num": 2}
if (request.method == "POST"):
print("View hit due to AJAX call!") # // THIS CAN BE TRIGGERED ADEQUATELY!
context["num"] = 5
return render(request, 'num.html', context)
return render(request, 'override.html', context)
override.html
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="{% static 'js/num.js' %}" defer></script>
<title>Title</title>
</head>
<body class="">
<div class="">
{% include 'num.html' %}
</div>
</body>
</html>
num.html
<h1>{{ num }}</h1>
num.js
var postUrl = "http://localhost:8000/";
function getCSRFToken() {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, 10) == ('csrftoken' + '=')) {
cookieValue = decodeURIComponent(cookie.substring(10));
break;
}
}
}
return cookieValue;
}
$('html').click(function(){
values = [1, 2];
var jsonText = JSON.stringify(values);
$.ajax({
url: postUrl,
headers: { "X-CSRFToken": getCSRFToken(), "X-Requested-With": "XMLHttpRequest" },
type: 'POST',
data: jsonText, // note the data, jsonText, does not really matter. The Django context gets updated to 5 instead of 2.
traditional: true,
dataType: 'html',
success: function(result){
console.log("AJAX successful") // THIS CAN BE TRIGGERED ADEQUATELY!
}
});
});
【问题讨论】:
-
过去,当我进行 ajax 调用时,我通常有 2 个视图,一个用于更改数据,另一个用于检索我想要更新的模板的 html pice,其背后的原因是获取html 元素我不得不使用 XMLHttpRequest() 而不是普通的请求。我必须说我从来没有为此使用过 jquery。您是否已经尝试通过控制台记录结果?
-
您好,谢谢您的回复。是的,如果您查看 num.js 文件,有一行
console.log("AJAX successful") // THIS CAN BE TRIGGERED ADEQUATELY!已被充分触发。 view.py 也在print("View hit due to AJAX call!") # // THIS CAN BE TRIGGERED ADEQUATELY!行中被命中。您能否详细说明您拥有两种观点的方法?作为一个 Django 新手,我的假设是视图用于呈现 HTML 模板,但您说您有一个“更改数据”的视图? -
所以,我的意思是“你是否已经尝试控制台记录结果”它到 console.log(result) 以查看是否有一个 xml 附加到响应,如果有它只是方式通过 id 获取元素并将其设置为结果。使用 2 个视图来更改数据的视图就像 api 点一样只返回一个状态,例如 200 或 400,根据这个状态,您调用另一个 url 来获取新的 html pice 来更新您的模板。这可能不是最好的解决方案,所以如果您的函数返回 xml,这是一个更好的解决方案
-
是的,
result已充分打印。问题是我想要构建的那种应用程序依赖于过滤view.py中的queryset,所以我必须依靠更新的context来重新渲染 HTML - 我不认为得到ID 的元素是我正在寻找的。另外,有必要依赖XML吗?我真的在考虑使用 HTML,因为 Django 的模板语言支持它,而且我对 XML 不太了解。 -
啊,谢谢你的回复。看来问题已经解决了——我绝对不能重新渲染 Django 模板本身,但我可以在 Django 视图中进行一些处理,然后渲染对 AJAX 回调函数的响应。然后,就像您建议的那样,我可以根据呈现的响应简单地修改 HTML。我认为视图的
render函数只是用于呈现 HTML - 结果它可以将响应传回 AJAX 调用...