Home > Net >  Django Query many to many field count miscalculation
Django Query many to many field count miscalculation

Time:03-08

I am creating a Django Blog Website and I am stuck at one point finding the no of likes on a specific post. I have created a webpage where all the posts are displayed. Now the problem I am facing is the no of likes are getting calculated wrong.

Post Model ->

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.PROTECT)
    title = models.CharField(max_length=255)   
    description = models.CharField(max_length=1000,null=True)
    Tags = models.CharField(max_length = 255,null=True,blank=True)
    Created_date = models.DateTimeField(auto_now_add=True)
    Updated_date = models.DateTimeField(auto_now=True)
    category = models.ForeignKey(Category, on_delete=models.PROTECT)
    Likes = models.ManyToManyField(to=User, related_name='Post_likes')
    favourites = models.ManyToManyField(to=User,blank=True,related_name="favourite")

    def __str__(self):
        return self.title

Query in Views.py file to fetch all the posts ->

posts =  Post.objects.select_related().prefetch_related('images_set').annotate(Count('comments_post')).annotate(Count('Likes')).all()

Now when I see the post.Likes__count in template it shows wrong count of 6 for one specific post but when I use post.likes.count() it shows count of 3.

for other posts they both show same result. I am unable to find out why it is happening. This is the result for that specific post ->

{'post_id': 22, 'user_id': 1, 'title': 'wkjdfh', 'description': 'kjwdfn', 'Tags': '.,smdf,m', 'category': <Category: Shoes>, 'userName': 'admin', 'images': <QuerySet [<Images: Images object (10)>, <Images: Images object (11)>, <Images: Images object (12)>, <Images: Images object (13)>]>, 'comments_count': 6, 'likesCount': 6, 'actualLikeCount': 3}

This is very strange that is happening and I know there would be a reason for this but I am unable to find out why.

CodePudding user response:

You don't need to use ".annotate(Count('Likes'))". To get the number of likes in the template you can do this:

{{post.Likes.count}}

CodePudding user response:

According to the Django docs:

Combining multiple aggregations with annotate() will yield the wrong results because joins are used instead of subqueries

link: https://docs.djangoproject.com/en/4.0/topics/db/aggregation/#combining-multiple-aggregations

Try using .annotate(Count(...), distinct=True).

  • Related