#33705 closed Bug (fixed)
IsNull() lookup cannot be used directly in filters.
Reported by: | Florian Apolloner | Owned by: | David Wobrock |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 4.0 |
Severity: | Release blocker | Keywords: | |
Cc: | Florian Apolloner, David Wobrock | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The docs in https://docs.djangoproject.com/en/4.0/ref/models/lookups/#django.db.models.Lookup seem to suggest that
<lhs>__<lookup_name>=<rhs>
is somewhat equivalent to
<lookup_name>(<lhs>, <rhs>)
This does work for some lookups, but not for IsNull
:
>>> from django.contrib.auth.models import User >>> from django.db.models import F >>> from django.db.models.lookups import GreaterThan, IsNull >>> User.objects.filter(GreaterThan(F('pk'), 1000)) DEBUG 2022-05-13 10:45:10,907 utils 63853 (0.006) SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" > (1000) LIMIT 21; args=(1000,); alias=default <QuerySet []> >>> User.objects.filter(IsNull(F('pk'), True)) Traceback (most recent call last): File "<console>", line 1, in <module> File "/home/florian/dev/bap/observer/server/__pypackages__/3.10/lib/django/db/models/manager.py", line 85, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/home/florian/dev/bap/observer/server/__pypackages__/3.10/lib/django/db/models/query.py", line 1071, in filter return self._filter_or_exclude(False, args, kwargs) File "/home/florian/dev/bap/observer/server/__pypackages__/3.10/lib/django/db/models/query.py", line 1089, in _filter_or_exclude clone._filter_or_exclude_inplace(negate, args, kwargs) File "/home/florian/dev/bap/observer/server/__pypackages__/3.10/lib/django/db/models/query.py", line 1096, in _filter_or_exclude_inplace self._query.add_q(Q(*args, **kwargs)) File "/home/florian/dev/bap/observer/server/__pypackages__/3.10/lib/django/db/models/sql/query.py", line 1502, in add_q clause, _ = self._add_q(q_object, self.used_aliases) File "/home/florian/dev/bap/observer/server/__pypackages__/3.10/lib/django/db/models/sql/query.py", line 1532, in _add_q child_clause, needed_inner = self.build_filter( File "/home/florian/dev/bap/observer/server/__pypackages__/3.10/lib/django/db/models/sql/query.py", line 1370, in build_filter condition = filter_expr.resolve_expression(self, allow_joins=allow_joins) File "/home/florian/dev/bap/observer/server/__pypackages__/3.10/lib/django/db/models/lookups.py", line 174, in resolve_expression c.rhs = self.rhs.resolve_expression( AttributeError: 'bool' object has no attribute 'resolve_expression'
Change History (9)
comment:1 by , 3 years ago
Summary: | IsNull-Lookup not usable → IsNull() lookup cannot be used directly in filters. |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 3 years ago
Cc: | added |
---|---|
Has patch: | set |
Patch needs improvement: | set |
comment:3 by , 2 years ago
Owner: | changed from | to
---|---|
Patch needs improvement: | unset |
Status: | new → assigned |
I used the same PR but changed the approach a bit.
It's the most straightforward approach I could think of. Let me know what you think :)
follow-up: 5 comment:4 by , 2 years ago
Shouldn't this be considered a release blocker since it's a bug in a newly released feature in Django 4.0?
comment:5 by , 2 years ago
Severity: | Normal → Release blocker |
---|---|
Version: | dev → 4.0 |
Replying to Simon Charette:
Shouldn't this be considered a release blocker since it's a bug in a newly released feature in Django 4.0?
Good catch! I missed that it's a new feature.
comment:6 by , 2 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
Here is a draft PR with failing tests.
Just a quick shot, trying to fix the issue with the approach of letting the
IsNull
handleValue
objects internally instead ofbool
s. But that might have quite a large impact for such a small change.