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