如何优化查询 django rest-framework
Posted
技术标签:
【中文标题】如何优化查询 django rest-framework【英文标题】:How can I optimize queries django rest-framework 【发布时间】:2018-11-29 16:40:32 【问题描述】:我有以下序列化程序
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")
模型视图集
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)
Querys
如何优化对基地的访问,即减少查询次数
【问题讨论】:
【参考方案1】:通过使用.prefetch_related(..)
一次获取相关的Auto
实例:
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
对象,并通过单个 获取所有这些对象到内存中也是。
因此Auto
对象被批量 加载,而不是每次为特定 Marca
对象获取Auto
s 时都懒惰地加载。
这种优化记录在@Jerin Peter George 提到的文章中:"Optimizing slow Django REST Framework performance"。
本文还讨论了如何在 serializer 一侧指定此类预取,以便在完成其他任务的情况下,预取不完成。所以我们可以例如写:
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 Query Optimization的最好的文章之一 @JerinPeterGeorge:谢谢。我在答案中添加了文章的链接。以上是关于如何优化查询 django rest-framework的主要内容,如果未能解决你的问题,请参考以下文章