Ticket #6821: aggregate.diff
File aggregate.diff, 4.2 KB (added by , 17 years ago) |
---|
-
django/db/models/sql/query.py
55 55 self.start_meta = None 56 56 57 57 # SQL-related attributes 58 self.aggregates = [] 58 59 self.select = [] 59 60 self.tables = [] # Aliases in the order they are created. 60 61 self.where = where() … … 139 140 obj.standard_ordering = self.standard_ordering 140 141 obj.start_meta = self.start_meta 141 142 obj.select = self.select[:] 143 obj.aggregates = self.aggregates[:] 142 144 obj.tables = self.tables[:] 143 145 obj.where = deepcopy(self.where) 144 146 obj.where_class = self.where_class … … 171 173 row = self.resolve_columns(row, fields) 172 174 yield row 173 175 176 def get_aggregation(self): 177 for field in self.select: 178 self.group_by.append(field) 179 self.select.extend(self.aggregates) 180 self.aggregates = [] 181 #print self.as_sql() 182 #print self.select 183 184 get_name = lambda x : isinstance(x, tuple) and x[1] or x.aliased_name 185 186 if self.group_by: 187 data = self.execute_sql(MULTI) 188 result = [] 189 for rs in data.next(): 190 result.append(dict(zip([get_name(i) for i in self.select], rs))) 191 return result 192 else: 193 data = self.execute_sql(SINGLE) 194 return dict(zip([get_name(i) for i in self.select], data)) 195 174 196 def get_count(self): 175 197 """ 176 198 Performs a COUNT() query using the current filter constraints. … … 806 828 self.fill_related_selections(f.rel.to._meta, alias, cur_depth + 1, 807 829 used, next, restricted) 808 830 831 def add_aggregate(self, aggregate_expr, aliased_name, model): 832 """ 833 Adds a single aggregate expression to the Query 834 """ 835 #TODO: Aliases, Joins 836 837 field_list = aggregate_expr.split(LOOKUP_SEP) 838 aggregate_func = field_list.pop() 839 840 opts = model._meta 841 842 field_name = field_list[0] 843 844 #if len(field_list) > 1: 845 # field, target, opts, join_list, last = self.setup_joins( 846 # field_list, opts, self.get_initial_alias(), False) 847 848 #Review Aliases 849 class AggregateNode: 850 def __init__(self, field_name, aggregate_func, aliased_name): 851 self.field_name = field_name 852 self.aggregate_func = aggregate_func 853 self.aliased_name = aliased_name 854 self.alias = '' #get table alias 855 856 def as_sql(self, quote_func=None): 857 return '%s(%s)' % (self.aggregate_func.upper(), 858 self.field_name) 859 860 self.aggregates.append(AggregateNode(field_name, aggregate_func, aliased_name)) 861 809 862 def add_filter(self, filter_expr, connector=AND, negate=False, trim=False, 810 863 merge_negated=False): 811 864 """ -
django/db/models/query.py
154 154 setattr(obj, k, row[index_end + i]) 155 155 yield obj 156 156 157 def aggregate(self, *args, **kwargs): 158 """ 159 Returns the aggregation over the current model as values (or so it should). 160 """ 161 if args: 162 TypeError('Unexpected positional arguments') 163 164 for (aggregate_expr, alias) in kwargs.items(): 165 self.query.add_aggregate(aggregate_expr, alias, self.model) 166 return self.query.get_aggregation() 167 157 168 def count(self): 158 169 """ 159 170 Performs a SELECT COUNT() and returns the number of records as an … … 328 339 Returns a new QuerySet that is a copy of the current one. This allows a 329 340 QuerySet to proxy for a model manager in some cases. 330 341 """ 331 return self._clone() 342 return self._clone() 332 343 333 344 def filter(self, *args, **kwargs): 334 345 """