【问题标题】:Re-render Django view based on jQuery-initiated AJAX POST request基于 jQuery 发起的 AJAX POST 请求重新渲染 Django 视图
【发布时间】: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 调用...

标签: html jquery django ajax


【解决方案1】:

如果这部分代码

success: function(result){
            console.log(result)
        }

打印 num.html 的内容,您可以更改 num.html 以获取 h1 id 为

num.hml

<h1 id="numberToChange">{{ num }}</h1>

在你的 num.js 中

$('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){
            document.getElementById("numberToChange").innerHTML = result}
    });
});

【讨论】:

  • 感谢您的回答!如果我有更多积分,我会支持你的答案,但不幸的是我是新用户。
  • 没问题,很高兴能帮到你
猜你喜欢
  • 2021-09-13
  • 1970-01-01
  • 2020-02-27
  • 2015-05-24
  • 2021-07-19
  • 2017-06-23
  • 1970-01-01
  • 2021-09-13
  • 2014-09-18
相关资源
最近更新 更多