Reputation: 524
I want to get the count of likes for all the post written by particular author. I have tried something like below,
Post.objects.filter(author=1).liked.count()
but, it returns
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'QuerySet' object has no attribute 'liked'
I'm able to fetch the like count for particular post by,
Post.objects.filter(author=1).first().liked.count()
How do I handle this logic in my views.py file?
models.py:
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField(validators=[MinLengthValidator(200)])
liked = models.ManyToManyField(User, default=None, blank=True, related_name = 'liked')
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name = 'author')
def __str__(self):
return self.title
@property
def num_likes(self):
return self.liked.all().count()
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
LIKE_CHOICES = (
('Like', 'Like'),
('Unlike', 'Unlike'),
)
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
value = models.CharField(choices= LIKE_CHOICES,default='Like', max_length=10)
def __str__(self):
return str(self.post)
Upvotes: 0
Views: 41
Reputation: 51978
You can try like this with aggregation
:
from django.db.models import Count, Sum
Post.objects.filter(author=1).annotate(like_count=Count('liked')).aggregate(total_likes=Sum('like_count'))['total_likes']
FYI if you have a ManyToMany relation through
Like
model, then you can use this:
Like.objects.filter(post__author_id=1).count()
Or
Like.objects.filter(post__author=request.user).count()
Upvotes: 1
Reputation: 1
Okay so this is a very basic one filter gives you queryset not an object. Consider it like this a = [object1]
what you are trying to access here is a.field which is giving you that error so when you are trying to do a.first().field it translates to object1.field so you are getting the count.
Now to handle this what you can do is instead of filter you can use get something like post.objects.get(condition) > this will return you the specific object
but the downside of using get over filter is if the condition does not satisfy filter return a empty queryset where the get will raise an exception so you have to handle that.
Upvotes: 0