[Django]-Getting a count of objects in a queryset in Django

198๐Ÿ‘

โœ…

To get the number of votes for a specific item, you would use:

vote_count = Item.objects.filter(votes__contest=contestA).count()

If you wanted a break down of the distribution of votes in a particular contest, I would do something like the following:

contest = Contest.objects.get(pk=contest_id)
votes   = contest.votes_set.select_related()

vote_counts = {}

for vote in votes:
  if not vote_counts.has_key(vote.item.id):
    vote_counts[vote.item.id] = {
      'item': vote.item,
      'count': 0
    }

  vote_counts[vote.item.id]['count'] += 1

This will create dictionary that maps items to number of votes. Not the only way to do this, but itโ€™s pretty light on database hits, so will run pretty quickly.

๐Ÿ‘คGary Chambers

26๐Ÿ‘

Another way of doing this would be using Aggregation. You should be able to achieve a similar result using a single query. Such as this:

from django.db.models import Count

Item.objects.values("contest").annotate(Count("id"))

I did not test this specific query, but this should output a count of the items for each value in contests as a dictionary.

๐Ÿ‘คsalomonvh

2๐Ÿ‘

Use related name to count votes for a specific contest

class Item(models.Model):
    name = models.CharField()

class Contest(models.Model);
    name = models.CharField()

class Votes(models.Model):
    user = models.ForeignKey(User)
    item = models.ForeignKey(Item)
    contest = models.ForeignKey(Contest, related_name="contest_votes")
    comment = models.TextField()

>>> comments = Contest.objects.get(id=contest_id).contest_votes.count()
๐Ÿ‘คsifar96

0๐Ÿ‘

You can use len() to get the count of contestAโ€™s votes:

current_vote = len(Item.objects.filter(votes__contest=contestA))

Actually, len() is used with select_for_update() as shown below:

current_vote = len(Item.objects.select_for_update().filter(votes__contest=contestA))

Because select_for_update() doesnโ€™t work with count() as shown below:

current_vote = Item.objects.select_for_update().filter(votes__contest=contestA).count()

You can see my answer explaning about select_for_update() with count() or len().

Leave a comment