I have a following model:
class VotingRound(models.Model):
pass # here are some unimportant fields
class Vote(models.Model):
voting_round = models.ForeignKey(VotingRound)
vote = models.CharField(choices=...)
Now I have instance of VotingRound and I would like to get to know how many times was each value represented. This is easily done through collections.Counter:
>>> Counter(voting_round_instance.vote_set.values_list('vote', flat=True))
Counter({u'decline': 8, u'neutral': 5, u'approve': 4})
Now I would like to know if there is a way to do this with Django aggregation techniques....
I have found this module, but before using it I wanted to know if there is native way to do it.
yes, you can!
from django.db.models import Count
voting_round_instance.vote_set.values('vote') \
.annotate(count=Count('vote')).distinct()
EDIT : use order_by()
You may also need to make sure the default ordering does not mess up your aggregation. This is especially true when using related object managers.
https://docs.djangoproject.com/en/1.8/topics/db/aggregation/#interaction-with-default-ordering-or-order-by
Fields that are mentioned in the order_by() part of a queryset (or which are used in the default ordering on a model) are used when selecting the output data, even if they are not otherwise specified in the values() call. These extra fields are used to group “like” results together and they can make otherwise identical result rows appear to be separate. This shows up, particularly, when counting things.
from django.db.models import Count
voting_round_instance.vote_set.values('vote') \
.annotate(count=Count('vote')) \
.distinct().order_by()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With