Skip to content

Commit

Permalink
Minor refactoring of must_call_distinct (#4215)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomchristie authored Jun 23, 2016
1 parent 90bb0c5 commit e1f7cc4
Showing 1 changed file with 8 additions and 6 deletions.
14 changes: 8 additions & 6 deletions rest_framework/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,15 @@ def construct_search(self, field_name):
lookup = 'icontains'
return LOOKUP_SEP.join([field_name, lookup])

def must_call_distinct(self, opts, lookups):
def must_call_distinct(self, queryset, search_fields):
"""
Return True if 'distinct()' should be used to query the given lookups.
"""
for lookup in lookups:
if lookup[0] in self.lookup_prefixes:
lookup = lookup[1:]
parts = lookup.split(LOOKUP_SEP)
opts = queryset.model._meta
for search_field in search_fields:
if search_field[0] in self.lookup_prefixes:
search_field = search_field[1:]
parts = search_field.split(LOOKUP_SEP)
for part in parts:
field = opts.get_field(part)
if hasattr(field, 'get_path_info'):
Expand Down Expand Up @@ -195,10 +196,11 @@ def filter_queryset(self, request, queryset, view):
]
queryset = queryset.filter(reduce(operator.or_, queries))

if self.must_call_distinct(queryset.model._meta, search_fields):
if self.must_call_distinct(queryset, search_fields):
# Filtering against a many-to-many field requires us to
# call queryset.distinct() in order to avoid duplicate items
# in the resulting queryset.
# We try to avoid this is possible, for performance reasons.
queryset = distinct(queryset, base)
return queryset

Expand Down

0 comments on commit e1f7cc4

Please sign in to comment.