Django & Ajax - Кнопка "Like", как заставить ее работать для нескольких постов на странице?

Здесь уже поднималось много подобных вопросов, но пока не удалось исправить мою настройку. Я успешно создал кнопку 'like' со счетчиком, но она работает только на одном посте, которых на одной странице несколько (при нажатии кнопки like на другом посте, изменяется только первый).

Что нужно изменить в коде, чтобы он работал для всех постов?

HTML-кнопка

{% for news in newss %}
<div class="col-md-6">
                    
{% csrf_token %}
<button class="like-button" value="{{ news.id }}" > Like </button>
<span class="" id="like_count">{{ news.news_likes_count }}</span>

</div>
{% endfor %}

AJAX

<script>
  $(document).on('click', '.like-button', function (e) {
    e.preventDefault();
    $.ajax({
      type: 'POST',
      url: '{% url "like" %}',
      data: {
        newsid: $('.like-button').val(),
        csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
        action: 'post'
      },
      success: function (json) {
        document.getElementById("like_count").innerHTML = json['result']
      },
      error: function(xhr, errmsg, err) {

      }
    });
  })

</script>

views.py

@login_required
def like(request):
    if request.POST.get('action') == 'post':
        result = ''
        id = int(request.POST.get('newsid'))
        news = get_object_or_404(News, id=id)
        if news.news_likes.filter(id=request.user.id).exists():
            news.news_likes.remove(request.user)
            news.news_likes_count -= 1
            result = news.news_likes_count
            news.save()
        else:
            news.news_likes.add(request.user)
            news.news_likes_count += 1
            result = news.news_likes_count
            news.save()

        return JsonResponse({'result': result,})

urls.py

path('like/', views.like, name='like')

models.py

class News(models.Model):
    news_title = models.CharField(max_length=100)
    news_text = models.TextField(max_length=2000)
    news_author = models.CharField(max_length=150)
    news_created_date = models.DateTimeField(default=now)
    news_likes = models.ManyToManyField(User, related_name='n_like', default=None, blank=True)
    news_likes_count = models.BigIntegerField(default='0')

Вам нужно использовать значение кнопки clicked, поэтому:

data: {
    newsid: $(this).val(),
    csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
    action: 'post'
},

Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.


Note: You do not have to store the number of items of a ManyToManyField in another field. You can use .annotate(…) [Django-doc] when you need to determine this by the database. Storing this explicitly in a field is a form of data duplication, and it turns out that keeping these in sync is harder than what one might expect.

Вернуться на верх