Performance: Chaining querysets
Chaining querysets affects database query efficiency and page load speed by controlling how many queries are sent and how much data is processed.
Jump into concepts and practice - no test required
qs = Model.objects.filter(active=True).filter(category='books') list_final = list(qs)
qs1 = Model.objects.filter(active=True) qs2 = qs1.filter(category='books') list1 = list(qs1) list2 = list(qs2)
| Pattern | Database Queries | Data Transfer | Backend Load | Verdict |
|---|---|---|---|---|
| Separate queryset evaluations | Multiple queries | More data transferred | Higher CPU and DB load | [X] Bad |
| Chained queryset filters | Single query | Minimal data transferred | Lower CPU and DB load | [OK] Good |
save() and update() are not queryset chaining methods; get() returns a single instance, not suitable for chaining.qs = MyModel.objects.filter(active=True) qs2 = qs.filter(age__gte=18) qs3 = qs2.exclude(name__startswith='A')
qs3 contain?qs filters objects where active=True.qs2 further filters qs to include only those with age >= 18.qs3 excludes objects from qs2 whose name starts with 'A'.qs = MyModel.objects.all()[:10] qs = qs.filter(active=True)
[:10]) evaluates it and returns a list, not a queryset.qs is now a list, calling filter() on it causes an error or unexpected behavior.exclude(name__startswith='A' or 'B') is invalid syntax and exclude(name__startswith=['A', 'B']) is not supported.