| | 178 | def get_aggregation(self): |
| | 179 | for field in self.select: |
| | 180 | self.group_by.append(field) |
| | 181 | self.select.extend(self.aggregates) |
| | 182 | self.aggregates = [] |
| | 183 | #print self.as_sql() |
| | 184 | #print 'after', self.select |
| | 185 | |
| | 186 | get_name = lambda x : isinstance(x, tuple) and x[1] or x.aliased_name |
| | 187 | |
| | 188 | print 'final query', self.as_sql() |
| | 189 | |
| | 190 | if self.group_by: |
| | 191 | data = self.execute_sql(MULTI) |
| | 192 | result = [] |
| | 193 | for rs in data.next(): |
| | 194 | result.append(dict(zip([get_name(i) for i in self.select], rs))) |
| | 195 | else: |
| | 196 | data = self.execute_sql(SINGLE) |
| | 197 | result = dict(zip([get_name(i) for i in self.select], data)) |
| | 198 | |
| | 199 | self.select = [] |
| | 200 | return result |
| | 201 | |
| | 837 | def add_aggregate(self, aggregate_expr, aliased_name, model): |
| | 838 | """ |
| | 839 | Adds a single aggregate expression to the Query |
| | 840 | """ |
| | 841 | |
| | 842 | field_list = aggregate_expr.split(LOOKUP_SEP) |
| | 843 | opts = model._meta |
| | 844 | |
| | 845 | aggregate_func = field_list.pop() |
| | 846 | |
| | 847 | if len(field_list) > 1: |
| | 848 | field, target, opts, join_list, last = self.setup_joins( |
| | 849 | field_list, opts, self.get_initial_alias(), False) |
| | 850 | final = len(join_list) |
| | 851 | penultimate = last.pop() |
| | 852 | if penultimate == final: |
| | 853 | penultimate = last.pop() |
| | 854 | if len(join_list) > 1: |
| | 855 | extra = join_list[penultimate:] |
| | 856 | final = penultimate |
| | 857 | col = self.alias_map[extra[0]][LHS_JOIN_COL] |
| | 858 | else: |
| | 859 | col = target.column |
| | 860 | |
| | 861 | field_name = field_list.pop() |
| | 862 | alias = join_list[-1] |
| | 863 | alias = extra[final] |
| | 864 | else: |
| | 865 | field_name = field_list[0] |
| | 866 | alias = opts.db_table |
| | 867 | |
| | 868 | class AggregateNode: |
| | 869 | def __init__(self, field_name, aggregate_func, aliased_name, alias): |
| | 870 | self.field_name = field_name |
| | 871 | self.aggregate_func = aggregate_func |
| | 872 | self.aliased_name = aliased_name |
| | 873 | self.alias = alias |
| | 874 | |
| | 875 | def as_sql(self, quote_func=None): |
| | 876 | if not quote_func: |
| | 877 | quote_func = lambda x: x |
| | 878 | return '%s(%s.%s)' % (self.aggregate_func.upper(), |
| | 879 | quote_func(self.alias), |
| | 880 | quote_func(self.field_name)) |
| | 881 | |
| | 882 | self.aggregates.append(AggregateNode(field_name, aggregate_func, aliased_name, alias)) |
| | 883 | |