我如何优化查询Django Rest框架 [英] How can I optimize queries django rest-framework
问题描述
我有以下序列化器
class AutoSerializer(serializers.ModelSerializer):
class Meta:
model = Auto
fields = ("nombre",)
class MarcaSerializer(WritableNestedModelSerializer):
autos = AutoSerializer(many=True)
class Meta:
model = Marca
fields = ("codigo", "descripcion", "autos")
ModelViewSet
ModelViewSet
class MarcaViewSet(viewsets.ModelViewSet):
queryset = Marca.objects.all()
serializer_class = MarcaSerializer
def list(self, request, *args, **kwargs):
queryset = self.queryset
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
如何优化对基地的访问,即减少查询
How can you optimize access to the base, that is, make fewer inquiries
推荐答案
通过使用 .prefetch_related(..)
可获取相关的 Auto
实例一次获取:
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)
这将首先获取 Marca
对象,然后使用 JOIN
对于所有 Auto
对象t帽子是相关的,并且还通过单个提取所有这些对象到内存中。
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.
所以 Auto
对象被装载到 bulk 中,而不是每次为特定的 获取 Auto
时都会懒惰地加载 Marca
对象。
So the Auto
objects are loaded in bulk instead of lazily each time fetch the Auto
s for a specific Marca
object.
@Jerin Peter George提到的文章中记录了这种优化: 优化慢速Django REST Framework性能 。
This kind of optization is documented in the article mentioned by @Jerin Peter George: "Optimizing slow Django REST Framework performance".
本文还讨论了如何在 serializer 一侧指定此类预取,以防万一其他任务都完成了,则预取未完成。这样我们可以例如编写:
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")
然后写:
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)
这篇关于我如何优化查询Django Rest框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!