【问题标题】:Django search_fields adding DUPLICATE left outer join to django query if it have .annotateDjango search_fields 将 DUPLICATE 左外连接添加到 django 查询(如果它有 .annotate)
【发布时间】:2019-06-18 03:50:24
【问题描述】:

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'))

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

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

【问题讨论】:

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


    【解决方案1】:

    在使用 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 个表连接。

    抱歉,我的帖子不会帮助解决此案:prefetch_related 希望这对其他人有所帮助,因为我在搜索 https://code.djangoproject.com/ticket/18437 的解决方案时发现了这个

    【讨论】:

      【解决方案2】:

      我找到了解决此问题的方法。 我用 .extra('Query to get Appliance count') 替换了 annotate。 我没有在额外的查询中使用连接。所以最终查询只有单连接,没有重复连接。

      【讨论】:

      • extra会导致Group By错误,过滤器也很难用
      猜你喜欢
      • 2017-06-30
      • 2011-09-23
      • 2012-06-28
      • 1970-01-01
      • 2016-10-29
      • 2011-03-04
      • 2016-01-01
      • 1970-01-01
      相关资源
      最近更新 更多