diff options
| author | Ian Foote <python@ian.feete.org> | 2021-04-02 18:25:20 +0100 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-07-09 11:43:06 +0200 |
| commit | f42ccdd835e5b3f0914b5e6f87621c648136ea36 (patch) | |
| tree | 49f0a1ecbd05b4d8d0049cec21ad564a663b427f /django/db/models/sql | |
| parent | f5dccbafb957841d0867f0b153d7f7123f0ec83d (diff) | |
Fixed #27021 -- Allowed lookup expressions in annotations, aggregations, and QuerySet.filter().
Thanks Hannes Ljungberg and Simon Charette for reviews.
Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com>
Diffstat (limited to 'django/db/models/sql')
| -rw-r--r-- | django/db/models/sql/query.py | 6 | ||||
| -rw-r--r-- | django/db/models/sql/where.py | 19 |
2 files changed, 22 insertions, 3 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 87be8ea9f0..2412e6ad4e 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -1262,9 +1262,9 @@ class Query(BaseExpression): if hasattr(filter_expr, 'resolve_expression'): if not getattr(filter_expr, 'conditional', False): raise TypeError('Cannot filter against a non-conditional expression.') - condition = self.build_lookup( - ['exact'], filter_expr.resolve_expression(self, allow_joins=allow_joins), True - ) + condition = filter_expr.resolve_expression(self, allow_joins=allow_joins) + if not isinstance(condition, Lookup): + condition = self.build_lookup(['exact'], condition, True) clause = self.where_class() clause.add(condition, AND) return clause, [] diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py index 2577e1d7a5..5a4da97396 100644 --- a/django/db/models/sql/where.py +++ b/django/db/models/sql/where.py @@ -208,6 +208,25 @@ class WhereNode(tree.Node): clone.resolved = True return clone + @cached_property + def output_field(self): + from django.db.models import BooleanField + return BooleanField() + + def select_format(self, compiler, sql, params): + # Wrap filters with a CASE WHEN expression if a database backend + # (e.g. Oracle) doesn't support boolean expression in SELECT or GROUP + # BY list. + if not compiler.connection.features.supports_boolean_expr_in_select_clause: + sql = f'CASE WHEN {sql} THEN 1 ELSE 0 END' + return sql, params + + def get_db_converters(self, connection): + return self.output_field.get_db_converters(connection) + + def get_lookup(self, lookup): + return self.output_field.get_lookup(lookup) + class NothingNode: """A node that matches nothing.""" |
