summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorEddy Adegnandjou <adegnandjoueddy12@gmail.com>2025-10-31 09:00:41 +0100
committerJacob Walls <jacobtylerwalls@gmail.com>2026-04-02 11:24:26 -0400
commitcec10f992be8eed5ed90506375ae5794cbb7069e (patch)
tree9a9fcb9fd206db469bd20a948539268902e88cdb /django
parent3fb37ef41103ad0624ed9e8c3f7b9190f4264ae2 (diff)
Fixed #20024 -- Fixed handling of __in lookups with None in exclude().
Thanks Simon Charette and Tim Graham for reviews, and Jason Hall for a prior iteration.
Diffstat (limited to 'django')
-rw-r--r--django/db/models/sql/query.py14
1 files changed, 12 insertions, 2 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 7a4cf843c1..8be560856b 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -13,7 +13,7 @@ import functools
import sys
import warnings
from collections import Counter, namedtuple
-from collections.abc import Iterator, Mapping
+from collections.abc import Iterable, Iterator, Mapping
from itertools import chain, count, product
from string import ascii_uppercase
@@ -1638,7 +1638,17 @@ class Query(BaseExpression):
):
lookup_class = targets[0].get_lookup("isnull")
col = self._get_col(targets[0], join_info.targets[0], alias)
- clause.add(lookup_class(col, False), AND)
+ # Use OR + IS NULL when RHS `in` values include None.
+ if (
+ lookup_type == "in"
+ # Check containers (not strings or bytes).
+ and isinstance(condition.rhs, Iterable)
+ and not isinstance(condition.rhs, (str, bytes))
+ and any(v is None for v in condition.rhs)
+ ):
+ clause.add(lookup_class(col, True), OR)
+ else:
+ clause.add(lookup_class(col, False), AND)
# If someval is a nullable column, someval IS NOT NULL is
# added.
if isinstance(value, Col) and self.is_nullable(value.target):