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 theUsermodel [Django-doc] directly. For more information you can see the referencing theUsermodel section of the documentation.
Note: You do not have to store the number of items of a
ManyToManyFieldin 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.