我有以下Serilizers
{'products': product.template(10, 35, 36, 34, 6, 3, 24, 28, 5, 26, 18, 4, 1, 2, 8, 37, 25, 16, 17, 14, 20, 11, 21, 31, 12, 9, 32, 29, 30, 27, 23, 13, 15, 33, 7, 19, 22, 38), 'categ_value': {'Physique': {'categ_name': 'Physique', 'valuation': 760512.0}, 'En vente': {'categ_name': 'En vente', 'valuation': 0.0}, 'Logiciel': {'categ_name': 'Logiciel', 'valuation': 0.0}, 'Services': {'categ_name': 'Services', 'valuation': 0.0}, 'Tous': {'categ_name': 'Tous', 'valuation': 0.0}}}
ModelViewSet
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")
如何优化对基地的访问,即减少查询
答案 0 :(得分:2)
通过使用.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
对象,并用 single < / em>也提取到内存中。
因此,将Auto
对象加载到批量中,而不是每次为特定的 Auto
每次获取Marca
时都懒惰加载对象。
@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)