Getting a count of objects in a queryset in django

DjangoDjango ModelsDjango Queryset

Django Problem Overview


How can I add a field for the count of objects in a database. I have the following models:

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)
    comment = models.TextField()

To find the votes for contestA I am using the following query in my view

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

This returns a queryset with all of the votes individually but I want to get the count votes for each item, anyone know how I can do that? thanks

Django Solutions


Solution 1 - Django

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.

Solution 2 - Django

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:

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.

Solution 3 - Django

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()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionthesteveView Question on Stackoverflow
Solution 1 - DjangoGary ChambersView Answer on Stackoverflow
Solution 2 - DjangosalomonvhView Answer on Stackoverflow
Solution 3 - Djangosifar96View Answer on Stackoverflow