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