diff options
Diffstat (limited to 'django/db/models/sql/query.py')
| -rw-r--r-- | django/db/models/sql/query.py | 14 |
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): |
