我如何优化查询Django Rest框架 [英] How can I optimize queries django rest-framework

查看:81
本文介绍了我如何优化查询Django Rest框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下序列化器

    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)

Qu erys

如何优化对基地的访问,即减少查询

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 Autos 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆