diff options
| author | Russell Keith-Magee <russell@keith-magee.com> | 2009-01-29 10:46:36 +0000 |
|---|---|---|
| committer | Russell Keith-Magee <russell@keith-magee.com> | 2009-01-29 10:46:36 +0000 |
| commit | cf37e4624a967f936ecbb5a4eefc9d38ed9d7892 (patch) | |
| tree | e44fab9a21ccdf130d85b6fb80c423181663f103 /django/db/models/sql/query.py | |
| parent | 08dd4176edc1019d9168608b55fe777512c641cb (diff) | |
Fixed #7210 -- Added F() expressions to query language. See the documentation for details on usage.
Many thanks to:
* Nicolas Lara, who worked on this feature during the 2008 Google Summer of Code.
* Alex Gaynor for his help debugging and fixing a number of issues.
* Malcolm Tredinnick for his invaluable review notes.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@9792 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/db/models/sql/query.py')
| -rw-r--r-- | django/db/models/sql/query.py | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 88847d87e1..4e46da6424 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -18,6 +18,7 @@ from django.db.models import signals from django.db.models.fields import FieldDoesNotExist from django.db.models.query_utils import select_related_descend from django.db.models.sql import aggregates as base_aggregates_module +from django.db.models.sql.expressions import SQLEvaluator from django.db.models.sql.where import WhereNode, Constraint, EverythingNode, AND, OR from django.core.exceptions import FieldError from datastructures import EmptyResultSet, Empty, MultiJoin @@ -1271,6 +1272,10 @@ class BaseQuery(object): else: lookup_type = parts.pop() + # By default, this is a WHERE clause. If an aggregate is referenced + # in the value, the filter will be promoted to a HAVING + having_clause = False + # Interpret '__exact=None' as the sql 'is NULL'; otherwise, reject all # uses of None as a query value. if value is None: @@ -1284,6 +1289,10 @@ class BaseQuery(object): value = True elif callable(value): value = value() + elif hasattr(value, 'evaluate'): + # If value is a query expression, evaluate it + value = SQLEvaluator(value, self) + having_clause = value.contains_aggregate for alias, aggregate in self.aggregate_select.items(): if alias == parts[0]: @@ -1340,8 +1349,13 @@ class BaseQuery(object): self.promote_alias_chain(join_it, join_promote) self.promote_alias_chain(table_it, table_promote) - self.where.add((Constraint(alias, col, field), lookup_type, value), - connector) + + if having_clause: + self.having.add((Constraint(alias, col, field), lookup_type, value), + connector) + else: + self.where.add((Constraint(alias, col, field), lookup_type, value), + connector) if negate: self.promote_alias_chain(join_list) |
