|
14 | 14 | from django.utils.translation import gettext_lazy as _
|
15 | 15 |
|
16 | 16 | from rest_framework import RemovedInDRF317Warning
|
17 |
| -from rest_framework.compat import coreapi, coreschema, distinct |
| 17 | +from rest_framework.compat import coreapi, coreschema |
18 | 18 | from rest_framework.settings import api_settings
|
19 | 19 |
|
20 | 20 |
|
@@ -127,12 +127,13 @@ def filter_queryset(self, request, queryset, view):
|
127 | 127 | conditions.append(reduce(operator.or_, queries))
|
128 | 128 | queryset = queryset.filter(reduce(operator.and_, conditions))
|
129 | 129 |
|
| 130 | + # Remove duplicates from results, if necessary |
130 | 131 | if self.must_call_distinct(queryset, search_fields):
|
131 |
| - # Filtering against a many-to-many field requires us to |
132 |
| - # call queryset.distinct() in order to avoid duplicate items |
133 |
| - # in the resulting queryset. |
134 |
| - # We try to avoid this if possible, for performance reasons. |
135 |
| - queryset = distinct(queryset, base) |
| 132 | + # inspired by django.contrib.admin |
| 133 | + # this is more accurate than .distinct form M2M relationship |
| 134 | + # also is cross-database |
| 135 | + queryset = queryset.filter(pk=models.OuterRef('pk')) |
| 136 | + queryset = base.filter(models.Exists(queryset)) |
136 | 137 | return queryset
|
137 | 138 |
|
138 | 139 | def to_html(self, request, queryset, view):
|
|
0 commit comments