Index: django/db/models/sql/query.py
===================================================================
--- django/db/models/sql/query.py	(revision 7274)
+++ django/db/models/sql/query.py	(working copy)
@@ -55,6 +55,7 @@
         self.start_meta = None
 
         # SQL-related attributes
+        self.aggregates = []
         self.select = []
         self.tables = []    # Aliases in the order they are created.
         self.where = where()
@@ -139,6 +140,7 @@
         obj.standard_ordering = self.standard_ordering
         obj.start_meta = self.start_meta
         obj.select = self.select[:]
+        obj.aggregates = self.aggregates[:]
         obj.tables = self.tables[:]
         obj.where = deepcopy(self.where)
         obj.where_class = self.where_class
@@ -171,6 +173,26 @@
                     row = self.resolve_columns(row, fields)
                 yield row
 
+    def get_aggregation(self):
+        for field in self.select:
+            self.group_by.append(field)
+        self.select.extend(self.aggregates)
+        self.aggregates = []
+        #print self.as_sql()
+        #print self.select
+
+        get_name = lambda x : isinstance(x, tuple) and x[1] or x.aliased_name
+
+        if self.group_by:
+            data = self.execute_sql(MULTI)
+            result = []
+            for rs in data.next():
+                result.append(dict(zip([get_name(i) for i in self.select], rs)))
+            return result
+        else:
+            data = self.execute_sql(SINGLE)
+            return dict(zip([get_name(i) for i in self.select], data))
+            
     def get_count(self):
         """
         Performs a COUNT() query using the current filter constraints.
@@ -806,6 +828,37 @@
             self.fill_related_selections(f.rel.to._meta, alias, cur_depth + 1,
                     used, next, restricted)
 
+    def add_aggregate(self, aggregate_expr, aliased_name, model):
+        """
+        Adds a single aggregate expression to the Query
+        """
+        #TODO: Aliases, Joins
+
+        field_list = aggregate_expr.split(LOOKUP_SEP)
+        aggregate_func = field_list.pop()
+        
+        opts = model._meta
+
+        field_name = field_list[0]
+
+        #if len(field_list) > 1:
+        #    field, target, opts, join_list, last = self.setup_joins(
+        #        field_list, opts, self.get_initial_alias(), False)
+            
+        #Review Aliases
+        class AggregateNode:
+            def __init__(self, field_name, aggregate_func, aliased_name):
+                self.field_name = field_name
+                self.aggregate_func = aggregate_func
+                self.aliased_name = aliased_name
+                self.alias = '' #get table alias
+                
+            def as_sql(self, quote_func=None):
+                return '%s(%s)' % (self.aggregate_func.upper(),
+                                   self.field_name)
+
+        self.aggregates.append(AggregateNode(field_name, aggregate_func, aliased_name))
+        
     def add_filter(self, filter_expr, connector=AND, negate=False, trim=False,
             merge_negated=False):
         """
Index: django/db/models/query.py
===================================================================
--- django/db/models/query.py	(revision 7274)
+++ django/db/models/query.py	(working copy)
@@ -154,6 +154,17 @@
                 setattr(obj, k, row[index_end + i])
             yield obj
 
+    def aggregate(self, *args, **kwargs):
+        """
+        Returns the aggregation over the current model as values (or so it should).
+        """
+        if args:
+            TypeError('Unexpected positional arguments')
+            
+        for (aggregate_expr, alias) in kwargs.items():
+            self.query.add_aggregate(aggregate_expr, alias, self.model)
+        return self.query.get_aggregation()
+
     def count(self):
         """
         Performs a SELECT COUNT() and returns the number of records as an
@@ -328,7 +339,7 @@
         Returns a new QuerySet that is a copy of the current one. This allows a
         QuerySet to proxy for a model manager in some cases.
         """
-        return self._clone()
+        return self._clone()        
 
     def filter(self, *args, **kwargs):
         """
