Проблема с асинхронным отображением <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.");
      });
  });
}
Вернуться на верх