Django ORM: counting orders per status with conditional aggregation

Backend Live Coding November 13, 2026 python

Get the number of orders per status in one query, and the number of paid/cancelled orders per customer.

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# ======================================================================
# Q: Get the number of orders per status in one query, and the number of
# paid/cancelled orders per customer.
# ======================================================================

Order.objects.values('status').annotate(n=Count('id')).order_by('status')
# [{'status': 'paid', 'n': 120}, ...]

# conditional aggregation: one query, many counts
Customer.objects.annotate(
    paid=Count('orders', filter=Q(orders__status='paid')),
    cancelled=Count('orders', filter=Q(orders__status='cancelled')),
)