From 653343cf32334a3d6e92872c0a7decdc7d8e9085 Mon Sep 17 00:00:00 2001 From: Pravin <91125540+p-r-a-v-i-n@users.noreply.github.com> Date: Mon, 20 Oct 2025 22:15:11 +0530 Subject: [PATCH] Add documentation on avoiding N+1 queries using select_related/prefetch_related (#9801) --- docs/api-guide/generic-views.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index 70bfa7992..4c81299c5 100644 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -102,6 +102,39 @@ For example: --- +### Avoiding N+1 Queries + +When listing objects (e.g. using `ListAPIView` or `ModelViewSet`), serializers may trigger an N+1 query pattern if related objects are accessed individually for each item. + +To prevent this, optimize the queryset in `get_queryset()` or by setting the `queryset` class attribute using [`select_related()`](https://docs.djangoproject.com/en/stable/ref/models/querysets/#select-related) and [`prefetch_related()`](https://docs.djangoproject.com/en/stable/ref/models/querysets/#prefetch-related), depending on the type of relationship. + +**For ForeignKey and OneToOneField**: + +Use `select_related()` to fetch related objects in the same query: + + def get_queryset(self): + return Order.objects.select_related("customer", "billing_address") + +**For reverse and many-to-many relationships**: + +Use `prefetch_related()` to efficiently load collections of related objects: + + def get_queryset(self): + return Book.objects.prefetch_related("categories", "reviews__user") + +**Combining both**: + + def get_queryset(self): + return ( + Order.objects + .select_related("customer") + .prefetch_related("items__product") + ) + +These optimizations reduce repeated database access and improve list view performance. + +--- + #### `get_object(self)` Returns an object instance that should be used for detail views. Defaults to using the `lookup_field` parameter to filter the base queryset.