Back to Articles
2024-02-18

Database Aggregations: Count, Sum, and Avg

Calculating statistics in Python loops is slow and memory-intensive. Django's aggregation framework allows you to push these calculations to the database. Use `aggregate()` when you need a summary of the entire queryset, and `annotate()` when you want to add a calculated field to each object in the list.

Scenario 1: Aggregate (Summary Stats)

Returns a dictionary of values for the whole table.

python
from django.db.models import Sum, Avg, Max

stats = Order.objects.aggregate(
    total_revenue=Sum('amount'),
    avg_order_value=Avg('amount'),
    highest_order=Max('amount')
)
# Result: {'total_revenue': 5000, 'avg_order_value': 25.5, ...}

Scenario 2: Annotate (Per Object Calculation)

Adds a virtual field to every object in the QuerySet.

python
from django.db.models import Count

# Add 'num_books' field to every Author
authors = Author.objects.annotate(num_books=Count('book'))

for author in authors:
    print(f"{author.name} wrote {author.num_books} books")