Повторное отображение представления Django на основе инициированного jQuery запроса AJAX POST

Проблема, с которой я столкнулся, связана с перерисовкой представления Django на основе контекста, который обновляется AJAX-запросом, инициированным jQuery. Причина, по которой мне нужен AJAX-запрос, заключается в том, что мне нужно изменить пользовательский интерфейс страницы без обновления страницы, что очень важно для того, что я хочу создать.

Пока что я могу вызвать AJAX-пост запрос на URL той же страницы, где должно произойти обновление, и Django view.py адекватно регистрирует, что он был вызван. Однако, хотя я могу воспроизвести возможность обновления контекста представления Django, представление, похоже, не перерисовывает обновленный HTML на основе обновленного контекста.

В теме Как перерисовать код шаблона django при вызове AJAX, похоже, описана именно моя проблема. Решение, за которое проголосовало большинство участников этой темы, состоит в том, чтобы иметь условие, которое срабатывает только в случае вызова AJAX, который рендерит только часть шаблона (не полную HTML страницу) - часть шаблона, которая соответствует обновляемому компоненту. Именно это воспроизводится в приведенных ниже фрагментах кода, но HTML не меняется в зависимости от обновленного контекста.

Прилагаются соответствующие фрагменты кода для простой попытки, где страница отображает <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!
        }
    });
});

Если эта часть кода

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}
    });
});
Вернуться на верх