Django 查询集将空值与空 OuterRef 匹配

Django queryset matching null value with null OuterRef

在 Django 中,我试图通过是否存在具有相同值的 Bar 对象来过滤 Foo 对象。 我下面的代码适用于非空值。但如果 Foo.baz 和 Bar.baz 都为空,我也希望它 return 为真。

Foo.objects.filter(Exists(Bar.objects.filter(baz=OuterRef('baz'), qux=OuterRef('qux'))

我知道 NULL 不等于 SQL 中的 NULL,所以尝试了如下各种公式:

baz__isnull=...

但我还差得远。有办法实现吗?

您可以注释 OuterRef('baz') 的值并在您的过滤器中使用它。由于您需要执行 OR 条件,因此您需要使用 Q objects [Django docs]. Also it looks like filtering on the annotated OuterRef will not work because of this bug having Ticket #31714,但我们可以通过使用 ExpressionWrapper 手动指定 output_field 来解决这个问题。因此,如果 bazIntegerField,您的查询将如下所示:

from django.db.models import ExpressionWrapper, F, IntegerField, Q

q_object = Q(baz=F('outer_baz')) | (Q(baz__isnull=True) & Q(outer_baz__isnull=True))

Foo.objects.filter(
    Exists(
        Bar.objects.annotate(
            outer_baz=ExpressionWrapper(
                OuterRef('baz'),
                output_field=IntegerField()
            ) # Workaround to overcome bug
        ).filter(
            q_object,
            qux=OuterRef('qux')
        )
    )
)