Loading django/db/models/expressions.py +1 −23 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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] Loading Loading @@ -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) Loading django/db/models/query_utils.py +0 −33 Original line number Diff line number Diff line Loading @@ -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): """ Loading Loading @@ -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 Loading docs/ref/models/expressions.txt +0 −17 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
django/db/models/expressions.py +1 −23 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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] Loading Loading @@ -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) Loading
django/db/models/query_utils.py +0 −33 Original line number Diff line number Diff line Loading @@ -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): """ Loading Loading @@ -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 Loading
docs/ref/models/expressions.txt +0 −17 Original line number Diff line number Diff line Loading @@ -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 Loading