A bug from queryset-refactor days: although the Query class has "group_by" and

"having" attributes, only the former was included in the resulting SQL, meaning
subclasses had to completely duplicate Query.as_sql() if they were using any
kind of grouping filtering on the results.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@9007 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2008-09-11 02:00:27 +00:00
parent 11fd9f2d84
commit e47cc781d8
2 changed files with 36 additions and 0 deletions

View File

@ -292,6 +292,11 @@ class Query(object):
grouping = self.get_grouping()
result.append('GROUP BY %s' % ', '.join(grouping))
if self.having:
having, h_params = self.get_having()
result.append('HAVING %s' % ', '.join(having))
params.extend(h_params)
if ordering:
result.append('ORDER BY %s' % ', '.join(ordering))
@ -573,6 +578,24 @@ class Query(object):
result.append(str(col))
return result
def get_having(self):
"""
Returns a tuple representing the SQL elements in the "having" clause.
By default, the elements of self.having have their as_sql() method
called or are returned unchanged (if they don't have an as_sql()
method).
"""
result = []
params = []
for elt in self.having:
if hasattr(elt, 'as_sql'):
sql, params = elt.as_sql()
result.append(sql)
params.extend(params)
else:
result.append(elt)
return result, params
def get_ordering(self):
"""
Returns list representing the SQL elements in the "order by" clause.

View File

@ -953,6 +953,19 @@ relations.
>>> len([x[2] for x in q.alias_map.values() if x[2] == q.LOUTER and q.alias_refcount[x[1]]])
1
A check to ensure we don't break the internal query construction of GROUP BY
and HAVING. These aren't supported in the public API, but the Query class knows
about them and shouldn't do bad things.
>>> qs = Tag.objects.values_list('parent_id', flat=True).order_by()
>>> qs.query.group_by = ['parent_id']
>>> qs.query.having = ['count(parent_id) > 1']
>>> expected = [t3.parent_id, t4.parent_id]
>>> expected.sort()
>>> result = list(qs)
>>> result.sort()
>>> expected == result
True
"""}
# In Python 2.3 and the Python 2.6 beta releases, exceptions raised in __len__