summaryrefslogtreecommitdiff
path: root/django/db/models/sql
diff options
context:
space:
mode:
Diffstat (limited to 'django/db/models/sql')
-rw-r--r--django/db/models/sql/query.py23
1 files changed, 21 insertions, 2 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index cf527b18b0..6111a88118 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1193,7 +1193,7 @@ class Query(object):
entry.negate()
self.where.add(entry, AND)
break
- if field.null:
+ if self.is_nullable(field):
# In SQL NULL = anyvalue returns unknown, and NOT unknown
# is still unknown. However, in Python None = anyvalue is False
# (and not False is True...), and we want to return this Python's
@@ -1396,7 +1396,8 @@ class Query(object):
opts, target)
alias = self.join((alias, table, from_col, to_col),
- exclusions=exclusions, nullable=field.null)
+ exclusions=exclusions,
+ nullable=self.is_nullable(field))
joins.append(alias)
else:
# Non-relation fields.
@@ -1946,6 +1947,24 @@ class Query(object):
self.select = [(select_alias, select_col)]
self.remove_inherited_models()
+ def is_nullable(self, field):
+ """
+ A helper to check if the given field should be treated as nullable.
+
+ Some backends treat '' as null and Django treats such fields as
+ nullable for those backends. In such situations field.null can be
+ False even if we should treat the field as nullable.
+ """
+ # We need to use DEFAULT_DB_ALIAS here, as QuerySet does not have
+ # (nor should it have) knowledge of which connection is going to be
+ # used. The proper fix would be to defer all decisions where
+ # is_nullable() is needed to the compiler stage, but that is not easy
+ # to do currently.
+ if ((connections[DEFAULT_DB_ALIAS].features.interprets_empty_strings_as_nulls)
+ and field.empty_strings_allowed):
+ return True
+ else:
+ return field.null
def get_order_dir(field, default='ASC'):
"""