Проблема с асинхронным отображением <form> с помощью fetch в javascript в приложении django
Я написал ajax запрос на jQuery, который я хочу переписать на чистый javascript, используя fetch
.
В настоящее время я использую следующее:
views.py
@login_required
def like_article(request, id):
article = get_object_or_404(Article, id=id)
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
liked = False
if article.likes.filter(id=request.user.id).exists():
article.likes.remove(request.user)
liked = False
else:
article.likes.add(request.user)
liked = True
context = {
'article': article,
'is_liked': liked,
'total_likes': article.total_likes(),
}
if is_ajax:
like_form = render_to_string('components/ajax_like.html', context, request=request)
return JsonResponse({'like_form': like_form})
url.py
path('like_article/<int:id>/', views.like_article, name='like_article'),
ajax_like.html
<form action="{% url 'like_article' article.id %}" method="POST">
{% csrf_token %}
{% if is_liked %}
<button type="submit" id="like" value="{{article.id}}" class="btn btn-clicked"><i class='bx bxs-like'></i></button>
{% else %}
<button type="submit" id="like" value="{{article.id}}" class="btn btn-to-be-clicked"><i class='bx bx-like'></i></button>
{% endif %}
{{ total_likes }} like{{ total_likes|pluralize }}
</form>
jQuery ajax запрос (работает нормально)
$(document).ready(function(event){
$(document).on('click', '#like', function(event){
event.preventDefault();
var id = $(this).attr('value');
$.ajax({
type: 'POST',
url: '{% url "like_optimazon" article.id %}',
data: {
'id':id,
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
dataType: 'json',
success: function(response){
$('#like-section').html(response['like_form'])
},
error: function(rs, e){
console.log(rs.responseText);
},
});
});
});
});
Ниже описано то, что я пытался сделать. В принципе, после нажатия кнопки like класс должен измениться с .btn-not-liked
на .btn-liked
и количество лайков должно увеличиться на 1. Я хотел бы сохранить ту же логику в бэкенде, но получаю ошибку The view articles.views.like_article didn't return an HttpResponse object. It returned None instead.
. Однако, когда я возвращаюсь на веб-страницу, счетчик и класс обновляются правильно.
function like_handeler(element) {
element.addEventListener("click", () => {
id = element.getAttribute("value");
liked = element.getAttribute("data-liked");
form = new FormData(this);
form.append("id", id);
form.append("is_liked", liked);
fetch('{% url "like_article" article.id %}', {
method: "POST",
body: form,
credentials: 'same-origin',
headers:{
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRFToken': '{{ csrf_token }}',
}
})
.then((res) => res.json())
.then((res) => {
console.log(res)
if (res.status == 200) {
if (res.is_liked === "yes") {
button.classList.toggle(".btn-not-liked");
element.setAttribute("data-liked", "no");
} else {
button.classList.toggle(".btn-liked");
element.setAttribute("data-liked", "yes");
}
count.textContent = res.like_count;
}
})
.catch(function (res) {
alert("Network Error. Please Check your connection.");
});
});
}