Ticket #9797: annotate-count.3.diff

File annotate-count.3.diff, 3.6 KB (added by Alex Gaynor, 16 years ago)

All tests pass, logic is a bit of a clusterfuck, but it's mostly in the right place

  • django/db/models/sql/aggregates.py

    diff --git a/django/db/models/sql/aggregates.py b/django/db/models/sql/aggregates.py
    index dd60aca..6510f58 100644
    a b class Aggregate(object):  
    2727    def relabel_aliases(self, change_map):
    2828        if self.col_alias in change_map:
    2929            self.col_alias = change_map[self.col_alias]
     30        if isinstance(self.lookup, (list, tuple)):
     31            self.lookup = (change_map.get(self.lookup[0], self.lookup[0]), self.lookup[1])
    3032
    3133    def field_name(self, quote_func):
    3234        if not quote_func:
    3335            quote_func = lambda x: x
    3436        if hasattr(self, 'col_alias'):
    3537            return '.'.join([quote_func(self.col_alias), quote_func(self.field.column)])
     38        elif isinstance(self.lookup, (list, tuple)):
     39            return ('%s.%s' % tuple([quote_func(c) for c in self.lookup]))
     40        elif hasattr(self.lookup, 'as_sql'):
     41            return self.lookup.as_sql(quote_func)
    3642        else:
    3743            return self.lookup
    3844
  • django/db/models/sql/query.py

    diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
    index 43c4f36..fe46e3d 100644
    a b class BaseQuery(object):  
    274274        """
    275275        Performs a COUNT() query using the current filter constraints.
    276276        """
    277         from subqueries import CountQuery
     277        from django.db.models import Count as AggCount
     278        from django.db.models.sql.aggregates import Count as AggCount2
    278279        obj = self.clone()
    279         obj.clear_ordering(True)
    280280        obj.clear_limits()
     281        obj.clear_ordering(True)
    281282        obj.select_related = False
    282283        obj.related_select_cols = []
    283284        obj.related_select_fields = []
     285       
    284286        if len(obj.select) > 1:
    285             obj = self.clone(CountQuery, _query=obj, where=self.where_class(),
    286                     distinct=False)
    287             obj.select = []
    288             obj.aggregate_select = {}
    289             obj.extra_select = {}
    290         obj.add_count_column()
    291         data = obj.execute_sql(SINGLE)
    292         if not data:
    293             return 0
    294         number = data[0]
     287            from django.db.models.sql.subqueries import AggregateQuery
     288            inner = obj
     289            obj = AggregateQuery(obj.model, obj.connection)
     290            obj.add_subquery(inner)
     291       
     292        if not obj.distinct:
     293            if not obj.select:
     294                obj.aggregate_select['f'] = AggCount2('*', distinct=obj.distinct)
     295            else:
     296                obj.aggregate_select['f'] = AggCount2(obj.select[0], distinct=obj.distinct)
     297        else:
     298            if not obj.select:
     299                obj.add_aggregate(AggCount('pk', distinct=obj.distinct), obj.model, 'f', True)
     300            else:
     301                obj.aggregate_select['f'] = AggCount2(obj.select[0], distinct=obj.distinct)
    295302
     303        number = obj.get_aggregation()['f']
     304       
    296305        # Apply offset and limit constraints manually, since using LIMIT/OFFSET
    297306        # in SQL (in variants that provide them) doesn't change the COUNT
    298307        # output.
  • tests/regressiontests/aggregation_regress/models.py

    diff --git a/tests/regressiontests/aggregation_regress/models.py b/tests/regressiontests/aggregation_regress/models.py
    index f97608e..cc096b7 100644
    a b Traceback (most recent call last):  
    121121...
    122122FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, id, isbn, name, pages, price, publisher, store, num_authors
    123123
     124>>> Book.objects.annotate(num_authors=Count('authors')).count()
     1256
    124126"""
    125127}
    126128
Back to Top