如果django search_fields具有.annotate

时间:2019-01-24 11:58:37

标签: django django-rest-framework django-queryset

Django search_fields将带有设备表的DUPLICATE左外部联接添加到Django查询中,因为它具有.annotate(appliances_count = Count('appliances'))

查看

class AppliancePoolViewSet(VneCommonViewSet):
    serializer_class = vne_serializers.AppliancePoolSerializer
    search_fields = ('pk', 'name', 'notes', 'appliances__name')

    # filter appliance pools by customer
    def get_queryset(self):
        customer = getattr(self.request.user, 'customer', None)
        if not customer:
            return models.AppliancePool.objects.none()
        return models.AppliancePool.objects.filter(
            customer=1).prefetch_related('appliances'
            ).annotate(appliance_count=Count('appliances'))

首先它添加用于注释的联接,然后search_field也再次添加相同的联接,因为它具有字段“ appliances__name”,这会导致Appliance_count的数据不正确。

如何限制由Django过滤器使用search_fields属性完成的重复联接的添加?

2 个答案:

答案 0 :(得分:0)

我为此找到了解决方法。 我用.extra('查询以获得设备数量')替换了注释。 我没有在额外查询中使用联接。因此,最终查询只有一个联接,没有重复联接。

答案 1 :(得分:0)

使用Django ORM时有一些注意事项:

  1. 首先,将通过以下方式复制表联接: https://docs.djangoproject.com/en/3.0/topics/db/queries/#spanning-multi-valued-relationships

我还发现,当我们在不同的地方使用相同的relation时会产生影响,例如:过滤器,注释 Django将认为所有这些都是单一的,不应合并

  1. 深入研究Django代码后,我发现了这一点: https://docs.djangoproject.com/en/3.0/ref/models/querysets/#filteredrelation-objects

这将有助于避免跨越关系,我们只有1个表联接。

很抱歉,我的帖子将对以下情况提供帮助:<{1>} 希望这对其他人有帮助,因为我在搜索https://code.djangoproject.com/ticket/18437

的解决方案时发现了这一点