Reputation: 15824
A django queryset contains user uploaded photos and their corresponding upvotes (from viewers).
I need to run a query which returns all the votes added together. Is there any way to use the ORM to return the aggregate votes? I'm assuming it would be faster than how I'm currently doing it (performance matters for me here).
Currently I'm trying the following:
yesterday = datetime.utcnow() - timedelta(hours = 24)
photos = Photo.objects.filter(upload_time__gte=yesterday)
cumulative_votes = 0
for photo in photos:
cumulative_votes += photo.total_votes
Upvotes: 0
Views: 366
Reputation: 844
here's a one-liner:
total_vote_sum = Photo.objects.filter(filter_stuff).aggregate(Sum("total_votes"))["total_votes__sum"]
quote from:
https://docs.djangoproject.com/es/1.10/topics/db/aggregation/#generating-aggregates-over-a-queryset
aggregate() is a terminal clause for a QuerySet that, when invoked, returns a dictionary of name-value pairs. The name is automatically generated from the name of the field and the aggregate function.
so queryset.aggregate(Sum('field'))
will return a dictionary like:
{"field__sum": 'result'}
with this in mind, we can get our desired result directly like so:
result = queryset.aggregate(Sum('field'))['field__sum']
Upvotes: 1
Reputation: 8526
You need to use Sum,or Count functions of Django db, Like this :
from django.db.models import Count, Sum
yesterday = datetime.utcnow() - timedelta(hours = 24)
photos = Photo.objects.filter(upload_time__gte=yesterday).aggregate(total_votes=Count('total_votes'))
photo_sum = photos['total_votes']
Or
from django.db.models import Count, Sum
yesterday = datetime.utcnow() - timedelta(hours = 24)
photos = Photo.objects.filter(upload_time__gte=yesterday).aggregate(total_votes=Sum('total_votes'))
photo_sum = photos['total_votes']
Thanks.
Upvotes: 1