Chaining QuerySets
In this page:
What Is Chaining?
Each QuerySet method like filter() or order_by() returns another QuerySet, so you can call another method right after it, building up a query piece by piece.
Example: What Is Chaining?
This first narrows results to tutorials in the Tutorial category, then sorts just those results alphabetically.
from core.models import Tutorial
# Chain filter() and order_by() together
Tutorial.objects.filter(category='Tutorial').order_by('title')
{# Django-only code -- models.py/views.py/urls.py/settings.py
snippets, or template markup using Django template tags/variables
-- can't run standalone via Judge0 or the browser preview, since
it needs a real Django project. Only this course's pure-Python
examples (example_lang == 'python', no Django imports) are
actually runnable, so those still get the button below. #}
Lazy Evaluation
Django doesn't actually query the database while you're chaining methods — it waits until you do something that needs the real data, like looping over the queryset.
Note: This laziness lets you build complex queries efficiently before running them.
Example: Lazy Evaluation
The database is only hit when the for loop actually iterates over qs, not when it was built.
from core.models import Tutorial
qs = Tutorial.objects.filter(category='Forms') # no query yet
qs = qs.order_by('title') # still no query
for t in qs: # query runs here
print(t.title)
{# Django-only code -- models.py/views.py/urls.py/settings.py
snippets, or template markup using Django template tags/variables
-- can't run standalone via Judge0 or the browser preview, since
it needs a real Django project. Only this course's pure-Python
examples (example_lang == 'python', no Django imports) are
actually runnable, so those still get the button below. #}
Combining filter() and exclude()
filter() keeps matching rows, while exclude() removes matching rows — chaining them lets you include one condition and rule out another.
Example: Combining filter() and exclude()
The result only includes published tutorials from the Tutorial category — both conditions apply together.
from core.models import Tutorial
# Tutorials in 'Tutorial' category, excluding drafts
Tutorial.objects.filter(category='Tutorial').exclude(is_published=False)
{# Django-only code -- models.py/views.py/urls.py/settings.py
snippets, or template markup using Django template tags/variables
-- can't run standalone via Judge0 or the browser preview, since
it needs a real Django project. Only this course's pure-Python
examples (example_lang == 'python', no Django imports) are
actually runnable, so those still get the button below. #}
- Thinking each chained call runs a separate database query immediately, when really they combine into one query that runs only when evaluated.
- Reassigning the same variable name across chained calls and losing track of which filters are still active.
- Calling .filter() after already slicing the queryset with [:n], which Django doesn't allow.
- QuerySet methods like filter(), exclude(), and order_by() return new QuerySets, so they can be chained.
- Chaining doesn't hit the database until the queryset is evaluated, e.g. by looping over it or printing it.
- Chained filters combine with AND logic by default.
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: