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
来解决这个问题。因此,如果 baz
是 IntegerField
,您的查询将如下所示:
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')
)
)
)
在 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
来解决这个问题。因此,如果 baz
是 IntegerField
,您的查询将如下所示:
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')
)
)
)