Gokul nath
Gokul nath

Reputation: 524

How to write queries to fetch queryset in Django

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

Answers (2)

ruddra
ruddra

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

Biswajeet Padhi
Biswajeet Padhi

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

Related Questions