Повторное отображение представления 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}
});
});