“Q”与“__in”的Django ORM查询结果不一致

时间:2017-02-21 22:20:42

标签: django django-models django-orm

我正在尝试查找我的某个模型的所有实例,这些实例的属性设置为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()返回420结果我错了吗?如果是这样,为什么?

Q查询做了我想要的事情,所以我最终会继续这样做,但我仍然很好奇为什么第三个查询没有按照我的意愿行事。

谢谢!

编辑:不确定它是否有所作为,但内容字段是models.TextField,订单字段是models.IntegerField

3 个答案:

答案 0 :(得分:3)

请注意,NULL == NULL在SQL中实际上是假的,您需要使用IS NULL来检查值是否为空。 Django非常聪明,可以将Q(content=None)转换为IS NULL语句,这就是为什么TextBlock.objects.filter(Q(content='')|Q(content=None)).count()会返回您期望的结果。

IN语句只能将值与其元素进行比较,不能进行IS NULL检查。要检查空值,您需要明确添加content=None或等效的content__isnull=True

使用__in的查询应该按预期对任何不包含NULL的值列表起作用。

答案 1 :(得分:0)

要检查内容是否为无,您不应该使用比较。 您必须在ORM中使用content__isnull (并且您可以将查询与Q对象结合起来,就像您正在做的那样)

答案 2 :(得分:0)

您使用isnull字段查找检查var customerId = customerFilter.Id; //Or something similar 值:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.QUICKBOOT_POWERON" />
    <receiver
        android:name=".BootReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            <action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
        </intent-filter>
    </receiver>