Reputation: 3574
I'm trying to find all instances of one of my models that has an attribute set either to None or to an empty string. I think I'm missing something about the ORM's __in query.
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
When I do this with an IntegerFIeld and not using None or empty strings, I get:
TextBlock.objects.filter(order=1).count()
> 575046
TextBlock.objects.filter(order=2).count()
> 11946
TextBlock.objects.filter(order__in=[1,2]).count()
> 586992
This is what I'd expect. Was I wrong to expect TextBlock.objects.filter(content__in=['', None]).count()
to return 420 results? If so, why?
The Q query does what I want, so I'll end up going with that, but I'm still curious about why that third query didn't do what I wanted.
Thanks!
EDIT: Not sure if it makes a difference, but the content field is a models.TextField and the order field is a models.IntegerField
Upvotes: 0
Views: 126
Reputation: 53699
Note that NULL == NULL
is actually false in SQL, and you need to use IS NULL
to check if a value is null. Django is smart enough to convert Q(content=None)
to an IS NULL
statement, that's why TextBlock.objects.filter(Q(content='')|Q(content=None)).count()
returns the results you'd expect.
An IN
statement can only compare a value against its elements, it can't do an IS NULL
check. To check against null values you need to explicitly add content=None
or the equivalent content__isnull=True
.
The query using __in
should work as expected for any list of values that doesn't include NULL
.
Upvotes: 3
Reputation: 19841
You check for None
values using isnull
field lookup:
TextBlock.objects.filter(Q(content='')|Q(content__isnull=True)).count()
Upvotes: 0
Reputation: 531
For checking if content is None you shouldn't use the comparison. You have to use content__isnull in the ORM (and you can combine queries with the Q object like you're doing)
Upvotes: 0