Django provides powerful tools for performing complex database operations using aggregation and annotation. These allow you to compute summary values and add calculated fields directly to querysets.
Sum, Avg, Count, and Faggregate() returns a dictionary of calculated values, while annotate() returns a queryset with extra fields attached to each record.
# Import aggregation functions
from django.db.models import Avg, Sum, Count
from .models import Product
# Calculate total price of all products
total_price = Product.objects.aggregate(Sum('price'))
# Calculate average product price
average_price = Product.objects.aggregate(Avg('price'))
# Count total number of products
product_count = Product.objects.aggregate(Count('id'))
# Import F expression and Count
from django.db.models import F, Count
from .models import Product, Order
# Add order count to each product
products = Product.objects.annotate(order_count=Count('order'))
# Calculate total price per order
orders = Order.objects.annotate(total_price=F('price') * F('quantity'))
# Combine annotate and aggregate for advanced stats
from django.db.models import Sum, Avg
from .models import Product
products = Product.objects.annotate(
total_sales=Sum('order__price') * Sum('order__quantity')
).aggregate(
average_sales=Avg('total_sales')
)
The final query first calculates total sales per product, then computes the average sales across all products using chained ORM methods.
See the difference between aggregate and annotate live. The table below represents a database of Orders.
| ID | Product | Price ($) | Quantity |
|---|
aggregate() for whole-query summariesannotate() for per-record calculationsF() for field-based math