Я создал функцию «лайков» постов на странице списка постов (где отображаются посты одного пользователя). Используя примеры из книги «Django по примерам», я нажимал кнопку ajax лайков под каждым постом. Но работает некорректно. В этом примере кнопка Like была создана для страницы с одним сообщением, и я попытался подогнать ее под страницу со списком сообщений (много сообщений на одной странице). Когда пу sh кнопка лайка в базе данных все нормально - я получил плюс один лайк за конкретный пост. Но во фронтэнде случаются странные вещи - количество лайков для всех постов меняется, как будто все посты связаны. И когда я ставлю лайки и непохожи, количество лайков для всего поста становится очень большим. Я думаю, это происходит, потому что в этом случае Ajax использует один и тот же селектор класса (вместо id) для всех сообщений. Я все еще не очень хорош в Django и Ajax и не могу найти способ заставить это работать правильно. Потрачено много времени на попытки исправить это и поиск в Google безрезультатно. Любая помощь доступна.
Ниже указан код.
Модель сообщения с полями лайков:
class Posts(models.Model):
author = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True, blank=True)
content = models.TextField()
image = models.ImageField(upload_to="posts/%Y/%m/%d", null=True,blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
users_like = models.ManyToManyField(settings.AUTH_USER_MODEL,
related_name='images_liked',
blank=True)
total_likes = models.PositiveIntegerField(db_index=True,
default=0)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("post_detail", kwargs={"slug": self.slug})
def slug_generator(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = unique_slug_generator(instance)
pre_save.connect(slug_generator, sender=Posts)
Функция post_like в view.py пользователя :
@ajax_required
@login_required
@require_POST
def post_like(request):
post_id = request.POST.get('id')
action = request.POST.get('action')
if post_id and action:
try:
post = Posts.objects.get(id=post_id)
if action == 'like':
post.users_like.add(request.user)
create_action(request.user, 'likes', post)
else:
post.users_like.remove(request.user)
return JsonResponse({'status':'ok'})
except:
pass
return JsonResponse({'status':'ok'})
Код в urls.py для этого:
urlpatterns = [
path('like/', views.post_like, name='like'),
...another urls...
]
html для кнопка лайков и подсчет лайков:
{% with total_likes=post.users_like.count users_like=post.users_like.all %}
<div class="image-info">
<div>
<span class="count">
<span class="total">{{ total_likes }}</span>
like{{ total_likes|pluralize }}
</span>
<a href="#" data-id="{{ post.id }}" data-action="{% if request.user in users_like %}un{% endif %}like" class="like button">
{% if request.user not in users_like %}
Like
{% else %}
Unlike
{% endif %}
</a>
</div>
</div>
<div class="image-likes">
</div>
{% endwith %}
И в том же файле html, где находится кнопка, внизу находится ajax код для функции лайков:
{% block domready %}
$('a.like').click(function(e){
e.preventDefault();
$.post('/like/',
{
id: $(this).data('id'),
action: $(this).data('action')
},
function(data){
if (data['status'] == 'ok')
{
var previous_action = $('a.like').data('action');
// toggle data-action
$('a.like').data('action', previous_action == 'like' ? 'unlike' : 'like');
// toggle link text
$('a.like').text(previous_action == 'like' ? 'Unlike' : 'Like');
// update total likes
var previous_likes = parseInt($('span.count .total').text());
$('span.count .total').text(previous_action == 'like' ? previous_likes + 2 : previous_likes - 2);
}
}
);
});
{% endblock %}