By using a .prefetch_related(..) that fetches the related Auto instances in one fetch:
class MarcaViewSet(viewsets.ModelViewSet):
queryset = Marca.objects.prefetch_related('autos').all()
serializer_class = MarcaSerializer
def list(self, request, *args, **kwargs):
queryset = self.queryset
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
This will first fetch the Marca objects, and then look with a JOIN for all the Auto objects that are related, and fetch all these objects with a single fetch into memory as well.
So the Auto objects are loaded in bulk instead of lazily each time fetch the Autos for a specific Marca object.
This kind of optization is documented in the article mentioned by @Jerin Peter George: "Optimizing slow Django REST Framework performance".
This article also discusses how to specify such prefetches at the side of the serializer, such that in case other tasks are done, the prefetch is not done. So we could for example write:
class AutoSerializer(serializers.ModelSerializer):
class Meta:
model = Auto
fields = ("nombre",)
class MarcaSerializer(WritableNestedModelSerializer):
autos = AutoSerializer(many=True)
@classmethod
def setup_eager_loading(cls, queryset):
return queryset.prefetch_related('autos')
class Meta:
model = Marca
fields = ("codigo", "descripcion", "autos")
and then write:
class MarcaViewSet(viewsets.ModelViewSet):
queryset = Marca.objects.all()
serializer_class = MarcaSerializer
def list(self, request, *args, **kwargs):
serializer = self.get_serializer
queryset = serializer.setup_eager_loading(self.queryset)
serializer = serializer(queryset, many=True)
return Response(serializer.data)