【发布时间】:2020-02-27 00:12:33
【问题描述】:
我试图把这个问题分解成最简单的例子。当请求是 ajax 时,使用更新的上下文渲染页面不会产生预期的结果。
index.html:
<html>
<body>
{% if templateVariable %}
<h1>{{ templateVariable }}</h1>
{% endif %}
<button id="testBtn">TEST</button>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$(function() {
$('#testBtn').click(function(event) {
$.ajax({
type: "POST",
url: "./",
data: {
'x' : 'x',
'csrfmiddlewaretoken' : '{{ csrf_token }}'
}
});
});
});
});
</script>
</body>
</html>
views.py
def index(request):
context = {}
if 'x' in request.POST:
context['templateVariable'] = 'I was updated via ajax'
print('ajax ran')
return render(request, 'index.html', context)
context['templateVariable'] = 'I was not updated via ajax'
print('ajax was not run')
return render(request, 'index.html', context)
-
当我第一次加载页面时,'ajax was not run' 被打印,templateVariable 是'我没有通过 ajax 更新',并且页面按预期在 h1 标记中呈现。
-
当我单击 testBtn 时,我希望 ajax 请求触发 if 语句,更新上下文,并在 h1 标记中使用“I was updated by ajax”呈现页面。
-
相反,打印了“ajax ran”,但在呈现页面时,templateVariable 仍然是“I was not updated by ajax”。 'ajax was not run' 仅在页面最初加载时打印一次。
为什么我没有得到预期的结果?
编辑:似乎每个人都同意您不能使用 ajax 请求返回渲染和更新上下文变量,但我仍然遇到问题,因为我相信这是可能的。这是一些替代代码:
index2.html:
<html>
<body>
{% if templateVariable %}
<h1>{{ templateVariable }}</h1>
{% endif %}
<h1 id="placeHolder"></h1>
<button id="testBtn">TEST</button>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$(function() {
$('#testBtn').click(function(event) {
$.ajax({
type: "POST",
url: "./",
data: {
'x' : 'x',
'csrfmiddlewaretoken' : '{{ csrf_token }}'
},
success: function (data) {
$('#placeHolder').html(data);
},
dataType: 'html'
});
});
});
});
</script>
</body>
</html>
views2.py
def index2(request):
context = {}
if 'x' in request.POST:
context['templateVariable'] = 'I was updated via ajax'
print('ajax ran')
return render_to_response('notIndex.html', context)
context['templateVariable'] = 'I was not updated via ajax'
print('ajax was not run')
return render(request, 'index.html', context)
notIndex.html:
{% if templateVariable %}
{{ templateVariable }}
{% endif %}
- 在此示例中,页面最初在上下文中使用 templateVariable 加载为“我没有通过 ajax 更新”。
- 点击 testBtn 时,ajax 请求会触发视图中的 if 块。这会使用更新的上下文呈现 notIndex.html。
- ajax调用成功函数将生成的html从notIndex.html设置为h1标签。
那么,如果页面与 ajax 调用来自的页面不同,为什么只能使用 ajax 触发页面呈现?
【问题讨论】:
-
因为使用 ajax 意味着您不会在浏览器中刷新整个页面,这意味着页面不会被 Django (重新)渲染,因此不会被更新。要使用来自 ajax 请求的数据更新页面,您必须自己使用 javascript 更新 html。
-
index.html 中的
if在页面首次加载时被评估。如果您想在加载页面后更改某些内容。你不能用 django-template 做到这一点。您必须使用 JavaScript 来做到这一点。 -
似乎传统的方法是使用更新的上下文渲染另一个页面,并将 index.html 上的某个占位符对象的 innerHTML 设置为在成功/完成函数中在该其他页面上生成的 html。在这种情况下,每次调用 render 时都会更新其他页面的上下文。那么为什么在渲染同一个页面时上下文不会更新呢?
-
因为您已经明确告诉浏览器不要选择使用Ajax。这就是重点。