Added support for modifying the effect of `DISTINCT` clauses so they

only consider some fields (PostgreSQL only).

For this, the ``distinct()`` QuerySet method now accepts an optional
list of model fields names and generates ``DISTINCT ON`` clauses on
these cases. Thanks Jeffrey Gelens and Anssi Kääriäinen for their work.

Fixes #6422.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17244 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Ramiro Morales 2011-12-22 20:42:40 +00:00
parent 03eb2907d5
commit 287565779d
16 changed files with 374 additions and 43 deletions

View file

@ -323,6 +323,8 @@ class QuerySet(object):
If args is present the expression is passed as a kwarg using
the Aggregate object's default alias.
"""
if self.query.distinct_fields:
raise NotImplementedError("aggregate() + distinct(fields) not implemented.")
for arg in args:
kwargs[arg.default_alias] = arg
@ -751,12 +753,14 @@ class QuerySet(object):
obj.query.add_ordering(*field_names)
return obj
def distinct(self, true_or_false=True):
def distinct(self, *field_names):
"""
Returns a new QuerySet instance that will select only distinct results.
"""
assert self.query.can_filter(), \
"Cannot create distinct fields once a slice has been taken."
obj = self._clone()
obj.query.distinct = true_or_false
obj.query.add_distinct_fields(*field_names)
return obj
def extra(self, select=None, where=None, params=None, tables=None,
@ -1179,7 +1183,7 @@ class EmptyQuerySet(QuerySet):
"""
return self
def distinct(self, true_or_false=True):
def distinct(self, fields=None):
"""
Always returns EmptyQuerySet.
"""