1 | Index: django/db/models/sql/query.py
|
---|
2 | ===================================================================
|
---|
3 | --- django/db/models/sql/query.py (revision 8818)
|
---|
4 | +++ django/db/models/sql/query.py (working copy)
|
---|
5 | @@ -84,6 +84,7 @@
|
---|
6 | self.extra_tables = ()
|
---|
7 | self.extra_where = ()
|
---|
8 | self.extra_params = ()
|
---|
9 | + self.extra_having = ()
|
---|
10 | self.extra_order_by = ()
|
---|
11 |
|
---|
12 | def __str__(self):
|
---|
13 | @@ -186,6 +187,7 @@
|
---|
14 | obj.extra_tables = self.extra_tables
|
---|
15 | obj.extra_where = self.extra_where
|
---|
16 | obj.extra_params = self.extra_params
|
---|
17 | + obj.extra_having = self.extra_having
|
---|
18 | obj.extra_order_by = self.extra_order_by
|
---|
19 | if self.filter_is_sticky and self.used_aliases:
|
---|
20 | obj.used_aliases = self.used_aliases.copy()
|
---|
21 | @@ -292,6 +294,9 @@
|
---|
22 | grouping = self.get_grouping()
|
---|
23 | result.append('GROUP BY %s' % ', '.join(grouping))
|
---|
24 |
|
---|
25 | + if self.extra_having:
|
---|
26 | + result.append('HAVING %s' % self.extra_having[0])
|
---|
27 | +
|
---|
28 | if ordering:
|
---|
29 | result.append('ORDER BY %s' % ', '.join(ordering))
|
---|
30 |
|
---|
31 | @@ -388,10 +393,14 @@
|
---|
32 | if self.extra_where and rhs.extra_where:
|
---|
33 | raise ValueError("When merging querysets using 'or', you "
|
---|
34 | "cannot have extra(where=...) on both sides.")
|
---|
35 | + if self.extra_having and rhs.extra_having:
|
---|
36 | + raise ValueError("When merging querysets using 'or', you "
|
---|
37 | + "cannot have extra(having=...) on both sides.")
|
---|
38 | self.extra_select.update(rhs.extra_select)
|
---|
39 | self.extra_tables += rhs.extra_tables
|
---|
40 | self.extra_where += rhs.extra_where
|
---|
41 | self.extra_params += rhs.extra_params
|
---|
42 | + self.extra_having += rhs.extra_having
|
---|
43 |
|
---|
44 | # Ordering uses the 'rhs' ordering, unless it has none, in which case
|
---|
45 | # the current ordering is used.
|
---|
46 | @@ -1567,7 +1576,7 @@
|
---|
47 | self.related_select_cols = []
|
---|
48 | self.related_select_fields = []
|
---|
49 |
|
---|
50 | - def add_extra(self, select, select_params, where, params, tables, order_by):
|
---|
51 | + def add_extra(self, select, select_params, where, params, tables, order_by, having):
|
---|
52 | """
|
---|
53 | Adds data to the various extra_* attributes for user-created additions
|
---|
54 | to the query.
|
---|
55 | @@ -1598,6 +1607,8 @@
|
---|
56 | self.extra_params += tuple(params)
|
---|
57 | if tables:
|
---|
58 | self.extra_tables += tuple(tables)
|
---|
59 | + if having:
|
---|
60 | + self.extra_having += tuple(having)
|
---|
61 | if order_by:
|
---|
62 | self.extra_order_by = order_by
|
---|
63 |
|
---|
64 | Index: django/db/models/query.py
|
---|
65 | ===================================================================
|
---|
66 | --- django/db/models/query.py (revision 8818)
|
---|
67 | +++ django/db/models/query.py (working copy)
|
---|
68 | @@ -567,14 +567,14 @@
|
---|
69 | return obj
|
---|
70 |
|
---|
71 | def extra(self, select=None, where=None, params=None, tables=None,
|
---|
72 | - order_by=None, select_params=None):
|
---|
73 | + order_by=None, select_params=None, having=None):
|
---|
74 | """
|
---|
75 | Adds extra SQL fragments to the query.
|
---|
76 | """
|
---|
77 | assert self.query.can_filter(), \
|
---|
78 | "Cannot change a query once a slice has been taken"
|
---|
79 | clone = self._clone()
|
---|
80 | - clone.query.add_extra(select, select_params, where, params, tables, order_by)
|
---|
81 | + clone.query.add_extra(select, select_params, where, params, tables, order_by, having)
|
---|
82 | return clone
|
---|
83 |
|
---|
84 | def reverse(self):
|
---|