I have a model named Post that has some fields like this :
class Post(models.Model):
title = models.CharField(max_length=500)
slug = models.SlugField(allow_unicode=True , unique=True , null=True , blank=True)
likes = models.ManyToManyField(User , blank=True , help_text="amount of likes")
likes_count = models.IntegerField(default=0 , help_text="amount of likes")
def __str__(self):
return self.title
and I have a view that needs to check if the user is in "likes" relation and do some stuff . But I don't know what to do ! this is my view:
def Like_view(request , slug):
post = get_object_or_404(Post , slug=slug)
if not request.user in post.likes:
post.likes.add(request.user)
post.likes_count += 1
post.save()
else:
post.likes.remove(request.user)
post.likes_count -= 1
post.save()
you dont need to save count of likes.
in your case:
likes_count = post.likes.count()
# or
likes_count = post.likes.aggregate(likes_count=Count('*')).get('likes_count')
https://docs.djangoproject.com/en/4.2/ref/models/querysets/#aggregation-functions
For your view I prefer to delete like, if returns nothing - it means you don't have a like and you can create it:
def Like_view(request , slug):
if not Post.likes.through.objects.filter(post__slug=slug, user = post.user).delete():
get_object_or_404(Post , slug=slug).likes.add(request.user)
And my opinion, the sheme can be better, with boolean checkbox in through model. In this case you can do only one DB call:
Post.likes.through.objects.filter(post__slug=slug, user = post.user).update(is_like=Q(is_like=False))