DRF ModelViewSet忽略prefetch / select_related?

时间:2016-04-19 08:28:14

标签: django django-rest-framework

我知道这个问题已被问过几次,但所有解决方案都不适合我。

我正在使用django-debug-toolbar,看到有数千个查询对相关对象。基本上模型中有大约2k行,DRF的API页面加载大约需要10秒。

我尝试过使用prefetch / select_related的所有可能组合,但它们不起作用。这是我的代码:

class A(models.Model):
    b = models.ForeignKey(B)

class B(models.Model):
    pass

class MyViewSet(viewsets.ModelViewSet):
    serializer_class = ASerializer
    queryset = A.objects.all().select_related('b')
    pagination_class = pagination.PageNumberPagination

    def get_queryset(self, *args, **kwargs):
        return super(MyViewSet, self).get_queryset(*args, **kwargs).select_related('b')

class ASerializer(serializers.ModelSerializer):

    class Meta:
        model = A

最大的罪魁祸首是分页类和序列化器。但是,我在DRF的内置分页类中找不到任何可疑的东西,在等待页面加载时,我在分页类的所有位置放了一些打印语句,它们都是立即打印的,所以绝对不是瓶子颈部。

下一个怀疑是ModelSerializer,我不确定发生了什么。最初,调试工具栏显示每页有大约1k个查询,每页有8个项目,然后我这样做了:

class MyViewSet(viewsets.ModelViewSet):
    serializer_class = ASerializer
    queryset = []
    pagination_class = pagination.PageNumberPagination

令我惊讶的是,虽然它现在显示0个项目,但是调试工具栏仍然显示有大约1k个查询,但仍然需要很长时间才能加载。现在,如果我将序列化程序类更改为具有更少行的其他模型:

class MyViewSet(viewsets.ModelViewSet):
    serializer_class = BSerializer
    queryset = []
    pagination_class = pagination.PageNumberPagination

class BSerializer(serializers.ModelSerializer):

    class Meta:
        model = B

页面加载速度更快,查询次数也更少。我现在唯一的假设是,不知何故,ModelSerializer在某些迭代过程中加载“几乎”整个结果集,但我找不到它。我说“差不多”的原因是因为总行数(约2k)与调试工具栏(1k)中报告的查询数之间存在差异。有什么想法吗?

0 个答案:

没有答案