diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 2b883c53ac8..79add29f368 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -5,8 +5,7 @@ from django.conf import settings from django.core.exceptions import FieldError from django.db.backends import utils as backend_utils from django.db.models import fields -from django.db.models.constants import LOOKUP_SEP -from django.db.models.query_utils import Q, refs_aggregate +from django.db.models.query_utils import Q from django.utils import six, timezone from django.utils.functional import cached_property @@ -306,24 +305,6 @@ class BaseExpression(object): c.copied = True return c - def refs_aggregate(self, existing_aggregates): - """ - Does this expression contain a reference to some of the - existing aggregates? If so, returns the aggregate and also - the lookup parts that *weren't* found. So, if - existing_aggregates = {'max_id': Max('id')} - self.name = 'max_id' - queryset.filter(max_id__range=[10,100]) - then this method will return Max('id') and those parts of the - name that weren't found. In this case `max_id` is found and the range - portion is returned as ('range',). - """ - for node in self.get_source_expressions(): - agg, lookup = node.refs_aggregate(existing_aggregates) - if agg: - return agg, lookup - return False, () - def get_group_by_cols(self): if not self.contains_aggregate: return [self] @@ -482,9 +463,6 @@ class F(Combinable): def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False): return query.resolve_ref(self.name, allow_joins, reuse, summarize) - def refs_aggregate(self, existing_aggregates): - return refs_aggregate(self.name.split(LOOKUP_SEP), existing_aggregates) - def asc(self): return OrderBy(self) diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py index 5d087869257..c0ae9030853 100644 --- a/django/db/models/query_utils.py +++ b/django/db/models/query_utils.py @@ -93,25 +93,6 @@ class Q(tree.Node): query.promote_joins(joins) return clause - @classmethod - def _refs_aggregate(cls, obj, existing_aggregates): - if not isinstance(obj, tree.Node): - aggregate, aggregate_lookups = refs_aggregate(obj[0].split(LOOKUP_SEP), existing_aggregates) - if not aggregate and hasattr(obj[1], 'refs_aggregate'): - return obj[1].refs_aggregate(existing_aggregates) - return aggregate, aggregate_lookups - for c in obj.children: - aggregate, aggregate_lookups = cls._refs_aggregate(c, existing_aggregates) - if aggregate: - return aggregate, aggregate_lookups - return False, () - - def refs_aggregate(self, existing_aggregates): - if not existing_aggregates: - return False - - return self._refs_aggregate(self, existing_aggregates) - class DeferredAttribute(object): """ @@ -301,20 +282,6 @@ def deferred_class_factory(model, attrs): return type(str(name), (model,), overrides) -def refs_aggregate(lookup_parts, aggregates): - """ - A helper method to check if the lookup_parts contains references - to the given aggregates set. Because the LOOKUP_SEP is contained in the - default annotation names we must check each prefix of the lookup_parts - for a match. - """ - for n in range(len(lookup_parts) + 1): - level_n_lookup = LOOKUP_SEP.join(lookup_parts[0:n]) - if level_n_lookup in aggregates and aggregates[level_n_lookup].contains_aggregate: - return aggregates[level_n_lookup], lookup_parts[n:] - return False, () - - def refs_expression(lookup_parts, annotations): """ A helper method to check if the lookup_parts contains references diff --git a/docs/ref/models/expressions.txt b/docs/ref/models/expressions.txt index d7c4105c4f6..aada3b448dc 100644 --- a/docs/ref/models/expressions.txt +++ b/docs/ref/models/expressions.txt @@ -526,23 +526,6 @@ calling the appropriate methods on the wrapped expression. A hook allowing the expression to coerce ``value`` into a more appropriate type. - .. method:: refs_aggregate(existing_aggregates) - - Returns a tuple containing the ``(aggregate, lookup_path)`` of the - first aggregate that this expression (or any nested expression) - references, or ``(False, ())`` if no aggregate is referenced. - For example:: - - queryset.filter(num_chairs__gt=F('sum__employees')) - - The ``F()`` expression here references a previous ``Sum()`` - computation which means that this filter expression should be - added to the ``HAVING`` clause rather than the ``WHERE`` clause. - - In the majority of cases, returning the result of ``refs_aggregate`` - on any nested expression should be appropriate, as the necessary - built-in expressions will return the correct values. - .. method:: get_group_by_cols() Responsible for returning the list of columns references by