Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add distinct method to FakeQuerySet #188

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions modelcluster/queryset.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,18 @@ def order_by(self, *fields):
clone = self.get_clone(results=self.results[:])
sort_by_fields(clone.results, fields)
return clone

def distinct(self, *fields):
unique_results = []
if not fields:
fields = [field.name for field in self.model._meta.fields if not field.primary_key]
seen_keys = set()
for result in self.results:
key = tuple(str(extract_field_value(result, field)) for field in fields)
if key not in seen_keys:
seen_keys.add(key)
unique_results.append(result)
return self.get_clone(results=unique_results)

# a standard QuerySet will store the results in _result_cache on running the query;
# this is effectively the same as self.results on a FakeQuerySet, and so we'll make
Expand Down
22 changes: 22 additions & 0 deletions tests/tests/test_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,28 @@ def test_meta_ordering(self):
albums = [album.name for album in beatles.albums.all()]
self.assertEqual(['With The Beatles', 'Please Please Me', 'Abbey Road'], albums)

def test_distinct_with_no_fields(self):
beatles = Band(name='The Beatles', albums=[
Album(name='Please Please Me', sort_order=1),
Album(name='With The Beatles', sort_order=2),
Album(name='Abbey Road', sort_order=2),
])

albums = [album.name for album in beatles.albums.order_by('sort_order').distinct()]
self.assertEqual(['Please Please Me', 'With The Beatles', 'Abbey Road'], albums)

def test_distinct_with_fields(self):
beatles = Band(name='The Beatles', albums=[
Album(name='Please Please Me', sort_order=1),
Album(name='With The Beatles', sort_order=2),
Album(name='Abbey Road', sort_order=2),
])
albums = [album.name for album in beatles.albums.order_by('sort_order').distinct('sort_order')]
self.assertEqual(['Please Please Me', 'With The Beatles'], albums)

albums = [album.name for album in beatles.albums.order_by('sort_order').distinct('name')]
self.assertEqual(['Please Please Me', 'With The Beatles', 'Abbey Road'], albums)

def test_parental_key_checks_clusterable_model(self):
from django.core import checks
from django.db import models
Expand Down
Loading