mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-18 04:02:35 +03:00
Use subquery to remove duplicates in SearchFilter
This commit is contained in:
parent
4f7e9ed3bb
commit
dee83cebf4
|
@ -3,7 +3,6 @@ The `compat` module provides support for backwards compatibility with older
|
|||
versions of Django/Python, and compatibility wrappers around optional packages.
|
||||
"""
|
||||
import django
|
||||
from django.conf import settings
|
||||
from django.views.generic import View
|
||||
|
||||
|
||||
|
@ -14,13 +13,6 @@ def unicode_http_header(value):
|
|||
return value
|
||||
|
||||
|
||||
def distinct(queryset, base):
|
||||
if settings.DATABASES[queryset.db]["ENGINE"] == "django.db.backends.oracle":
|
||||
# distinct analogue for Oracle users
|
||||
return base.filter(pk__in=set(queryset.values_list('pk', flat=True)))
|
||||
return queryset.distinct()
|
||||
|
||||
|
||||
# django.contrib.postgres requires psycopg2
|
||||
try:
|
||||
from django.contrib.postgres import fields as postgres_fields
|
||||
|
|
|
@ -14,7 +14,7 @@ from django.utils.encoding import force_str
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from rest_framework import RemovedInDRF317Warning
|
||||
from rest_framework.compat import coreapi, coreschema, distinct
|
||||
from rest_framework.compat import coreapi, coreschema
|
||||
from rest_framework.settings import api_settings
|
||||
|
||||
|
||||
|
@ -127,12 +127,13 @@ class SearchFilter(BaseFilterBackend):
|
|||
conditions.append(reduce(operator.or_, queries))
|
||||
queryset = queryset.filter(reduce(operator.and_, conditions))
|
||||
|
||||
# Remove duplicates from results, if necessary
|
||||
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 if possible, for performance reasons.
|
||||
queryset = distinct(queryset, base)
|
||||
# inspired by django.contrib.admin
|
||||
# this is more accurate than .distinct form M2M relationship
|
||||
# also is cross-database
|
||||
queryset = queryset.filter(pk=models.OuterRef('pk'))
|
||||
queryset = base.filter(models.Exists(queryset))
|
||||
return queryset
|
||||
|
||||
def to_html(self, request, queryset, view):
|
||||
|
|
Loading…
Reference in New Issue
Block a user