Aggregation & Annotation
Aggregation computes summary values across a QuerySet (total, average, max, min). Annotation adds per-object computed values. Both translate to efficient SQL and avoid loading all objects into Python.
15 min•By Priygop Team•Updated 2026
Aggregate Functions
- aggregate() — Returns a dictionary with computed values
- annotate() — Adds computed field to each object
- Count() — Count records
- Sum() — Sum of values
- Avg() — Average value
- Max() / Min() — Maximum/minimum values
- Combine with filter() for conditional aggregation
Aggregation Example
Aggregation Example
# from django.db.models import Count, Sum, Avg, Max, Min
# aggregate() — single summary value
# stats = Post.objects.aggregate(
# total_posts=Count('id'),
# avg_views=Avg('views_count'),
# max_views=Max('views_count'),
# total_views=Sum('views_count'),
# )
# # {'total_posts': 150, 'avg_views': 45.3, 'max_views': 1200, 'total_views': 6795}
# annotate() — per-object computed value
# authors = User.objects.annotate(
# total_posts=Count('posts'),
# avg_views=Avg('posts__views_count'),
# ).filter(total_posts__gt=5).order_by('-total_posts')
# for author in authors:
# print(f"{author.username}: {author.total_posts} posts, avg {author.avg_views:.0f} views")
# Conditional aggregation
# from django.db.models import Q
# Post.objects.aggregate(
# published=Count('id', filter=Q(published=True)),
# drafts=Count('id', filter=Q(published=False)),
# )
# Group by category
# Category.objects.annotate(
# num_posts=Count('posts'),
# total_views=Sum('posts__views_count'),
# ).values('name', 'num_posts', 'total_views')Tip
Tip
Use crispy-forms or django-widget-tweaks to render beautiful forms without writing HTML manually.
Diagram
Loading diagram…
QuerySets are LAZY — no DB hit until evaluated.
Common Mistake
Warning
Writing complex form HTML manually. Use {{ form.as_p }} or crispy-forms for consistent, clean rendering.
Practice Task
Note
(1) Install crispy-forms. (2) Render a form with {% crispy form %}. (3) Compare with manual HTML rendering.
Quick Quiz
Key Takeaways
- Aggregation computes summary values across a QuerySet (total, average, max, min).
- aggregate() — Returns a dictionary with computed values
- annotate() — Adds computed field to each object
- Count() — Count records