Index: django/db/models/sql/query.py
===================================================================
--- django/db/models/sql/query.py	(revision 8818)
+++ django/db/models/sql/query.py	(working copy)
@@ -84,6 +84,7 @@
         self.extra_tables = ()
         self.extra_where = ()
         self.extra_params = ()
+        self.extra_having = ()
         self.extra_order_by = ()
 
     def __str__(self):
@@ -186,6 +187,7 @@
         obj.extra_tables = self.extra_tables
         obj.extra_where = self.extra_where
         obj.extra_params = self.extra_params
+        obj.extra_having = self.extra_having
         obj.extra_order_by = self.extra_order_by
         if self.filter_is_sticky and self.used_aliases:
             obj.used_aliases = self.used_aliases.copy()
@@ -292,6 +294,9 @@
             grouping = self.get_grouping()
             result.append('GROUP BY %s' % ', '.join(grouping))
 
+        if self.extra_having:
+            result.append('HAVING %s' % self.extra_having[0])
+
         if ordering:
             result.append('ORDER BY %s' % ', '.join(ordering))
 
@@ -388,10 +393,14 @@
             if self.extra_where and rhs.extra_where:
                 raise ValueError("When merging querysets using 'or', you "
                         "cannot have extra(where=...) on both sides.")
+            if self.extra_having and rhs.extra_having:
+                raise ValueError("When merging querysets using 'or', you "
+                        "cannot have extra(having=...) on both sides.")
         self.extra_select.update(rhs.extra_select)
         self.extra_tables += rhs.extra_tables
         self.extra_where += rhs.extra_where
         self.extra_params += rhs.extra_params
+        self.extra_having += rhs.extra_having
 
         # Ordering uses the 'rhs' ordering, unless it has none, in which case
         # the current ordering is used.
@@ -1567,7 +1576,7 @@
         self.related_select_cols = []
         self.related_select_fields = []
 
-    def add_extra(self, select, select_params, where, params, tables, order_by):
+    def add_extra(self, select, select_params, where, params, tables, order_by, having):
         """
         Adds data to the various extra_* attributes for user-created additions
         to the query.
@@ -1598,6 +1607,8 @@
             self.extra_params += tuple(params)
         if tables:
             self.extra_tables += tuple(tables)
+        if having:
+            self.extra_having += tuple(having)	
         if order_by:
             self.extra_order_by = order_by
 
Index: django/db/models/query.py
===================================================================
--- django/db/models/query.py	(revision 8818)
+++ django/db/models/query.py	(working copy)
@@ -567,14 +567,14 @@
         return obj
 
     def extra(self, select=None, where=None, params=None, tables=None,
-              order_by=None, select_params=None):
+              order_by=None, select_params=None, having=None):
         """
         Adds extra SQL fragments to the query.
         """
         assert self.query.can_filter(), \
                 "Cannot change a query once a slice has been taken"
         clone = self._clone()
-        clone.query.add_extra(select, select_params, where, params, tables, order_by)
+        clone.query.add_extra(select, select_params, where, params, tables, order_by, having)
         return clone
 
     def reverse(self):
