Advanced Filtering (Q objects, lookups, annotations)
Q objects enable complex queries with OR, AND, NOT logic. Field lookups provide SQL-like conditions. Annotations add computed columns to QuerySets. Together, they give you full control over database queries.
20 min•By Priygop Team•Updated 2026
Q Objects & Lookups
- Q(condition) — Wrap conditions for complex logic
- Q(a) | Q(b) — OR: match a OR b
- Q(a) & Q(b) — AND: match a AND b
- ~Q(a) — NOT: exclude matching a
- Common lookups: __exact, __iexact, __contains, __icontains
- __gt, __gte, __lt, __lte — Comparisons
- __in, __range — IN and BETWEEN
- __isnull — IS NULL check
- __startswith, __endswith — String matching
Advanced Queries
Advanced Queries
# from django.db.models import Q, Count, Avg, Sum
# Q objects — complex conditions
# OR: posts that are published OR by admin
# Post.objects.filter(Q(published=True) | Q(author__username='admin'))
# AND with OR: published AND (python OR django in title)
# Post.objects.filter(
# Q(published=True) &
# (Q(title__icontains='python') | Q(title__icontains='django'))
# )
# NOT: exclude draft posts
# Post.objects.filter(~Q(published=False))
# Complex lookups
# Post.objects.filter(
# title__icontains='django',
# created_at__year=2026,
# views_count__gte=50,
# category__name__in=['Python', 'Django'],
# )
# Annotations — add computed columns
# from django.db.models import Count
# categories = Category.objects.annotate(
# post_count=Count('posts')
# )
# for cat in categories:
# print(f"{cat.name}: {cat.post_count} posts")
# Authors with most posts
# User.objects.annotate(
# num_posts=Count('posts')
# ).order_by('-num_posts')[:5]Tip
Tip
Use formsets for handling multiple forms on one page. ModelFormSet connects directly to querysets for bulk editing.
Diagram
Loading diagram…
QuerySets are LAZY — no DB hit until evaluated.
Common Mistake
Warning
Not handling form errors in templates. Always display {{ form.errors }} or {{ field.errors }} for user feedback.
Practice Task
Note
(1) Create a formset for multiple items. (2) Handle formset validation. (3) Save all forms in a loop.
Quick Quiz
Key Takeaways
- Q objects enable complex queries with OR, AND, NOT logic.
- Q(condition) — Wrap conditions for complex logic
- Q(a) | Q(b) — OR: match a OR b
- Q(a) & Q(b) — AND: match a AND b