"Q" 与“__in”不一致的 Django ORM 查询结果
Inconsistent Django ORM Query Results With "Q" vs "__in"
我正在尝试查找我的一个模型的所有实例,这些实例的属性设置为 None 或空字符串。我想我遗漏了一些关于 ORM 的 __in 查询。
TextBlock.objects.filter(content='').count()
>185
TextBlock.objects.filter(content=None).count()
>235
TextBlock.objects.filter(content__in=['', None]).count()
>185
TextBlock.objects.filter(Q(content='')|Q(content=None)).count()
>420
TextBlock.objects.filter(content__in=[None, '']).count()
>185
当我使用 IntegerFIeld 而不是使用 None 或空字符串时,我得到:
TextBlock.objects.filter(order=1).count()
> 575046
TextBlock.objects.filter(order=2).count()
> 11946
TextBlock.objects.filter(order__in=[1,2]).count()
> 586992
这是我所期望的。我期望 TextBlock.objects.filter(content__in=['', None]).count()
到 return 420 个结果是错误的吗?如果是,为什么?
Q 查询执行了我想要的操作,所以我最终会使用它,但我仍然很好奇为什么第三个查询没有执行我想要的操作。
谢谢!
编辑:不确定是否有所不同,但内容字段是 models.TextField 并且订单字段是 models.IntegerField
为了检查内容是否 None,您不应该使用比较。
你必须在 ORM 中使用 content__isnull
(您可以像现在一样将查询与 Q 对象结合起来)
您使用 isnull
字段查找检查 None
值:
TextBlock.objects.filter(Q(content='')|Q(content__isnull=True)).count()
注意NULL == NULL
在SQL中实际上是假的,你需要使用IS NULL
来检查一个值是否为空。 Django 足够聪明,可以将 Q(content=None)
转换为 IS NULL
语句,这就是为什么 TextBlock.objects.filter(Q(content='')|Q(content=None)).count()
returns 是您期望的结果。
IN
语句只能将值与其元素进行比较,不能进行 IS NULL
检查。要检查空值,您需要显式添加 content=None
或等效的 content__isnull=True
.
对于不包含 NULL
的任何值列表,使用 __in
的查询应该按预期工作。
我正在尝试查找我的一个模型的所有实例,这些实例的属性设置为 None 或空字符串。我想我遗漏了一些关于 ORM 的 __in 查询。
TextBlock.objects.filter(content='').count()
>185
TextBlock.objects.filter(content=None).count()
>235
TextBlock.objects.filter(content__in=['', None]).count()
>185
TextBlock.objects.filter(Q(content='')|Q(content=None)).count()
>420
TextBlock.objects.filter(content__in=[None, '']).count()
>185
当我使用 IntegerFIeld 而不是使用 None 或空字符串时,我得到:
TextBlock.objects.filter(order=1).count()
> 575046
TextBlock.objects.filter(order=2).count()
> 11946
TextBlock.objects.filter(order__in=[1,2]).count()
> 586992
这是我所期望的。我期望 TextBlock.objects.filter(content__in=['', None]).count()
到 return 420 个结果是错误的吗?如果是,为什么?
Q 查询执行了我想要的操作,所以我最终会使用它,但我仍然很好奇为什么第三个查询没有执行我想要的操作。
谢谢!
编辑:不确定是否有所不同,但内容字段是 models.TextField 并且订单字段是 models.IntegerField
为了检查内容是否 None,您不应该使用比较。 你必须在 ORM 中使用 content__isnull (您可以像现在一样将查询与 Q 对象结合起来)
您使用 isnull
字段查找检查 None
值:
TextBlock.objects.filter(Q(content='')|Q(content__isnull=True)).count()
注意NULL == NULL
在SQL中实际上是假的,你需要使用IS NULL
来检查一个值是否为空。 Django 足够聪明,可以将 Q(content=None)
转换为 IS NULL
语句,这就是为什么 TextBlock.objects.filter(Q(content='')|Q(content=None)).count()
returns 是您期望的结果。
IN
语句只能将值与其元素进行比较,不能进行 IS NULL
检查。要检查空值,您需要显式添加 content=None
或等效的 content__isnull=True
.
对于不包含 NULL
的任何值列表,使用 __in
的查询应该按预期工作。