diff --git a/rest_framework/filters.py b/rest_framework/filters.py index ff0b8e653..06dbba179 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -58,6 +58,7 @@ class DjangoFilterBackend(BaseFilterBackend): class Meta: model = queryset.model fields = filter_fields + return AutoFilterSet return None @@ -98,22 +99,24 @@ class SearchFilter(BaseFilterBackend): if not search_fields: return queryset - + if settings.DATABASES[queryset.db]["ENGINE"] == "django.db.backends.oracle": + # Remember queryset for Oracle db users + original_queryset = queryset orm_lookups = [self.construct_search(six.text_type(search_field)) for search_field in search_fields] - and_queries = [] + for search_term in self.get_search_terms(request): or_queries = [models.Q(**{orm_lookup: search_term}) for orm_lookup in orm_lookups] - and_queries.append(reduce(operator.or_, or_queries)) + queryset = queryset.filter(reduce(operator.or_, or_queries)) + if settings.DATABASES[queryset.db]["ENGINE"] != "django.db.backends.oracle": + # Oracle db don't support distinct on *LOB fields + queryset = queryset.distinct() + + if settings.DATABASES[queryset.db]["ENGINE"] == "django.db.backends.oracle": + # distinct analogue for Oracle users + queryset = original_queryset.filter(pk__in=set(queryset.values_list('pk', flat=True))) - if and_queries: - # According to Oracle DB limits there is no capability to make a DISTINT on *LOB - if settings.DATABASES[queryset.db]["ENGINE"] == "django.db.backends.oracle": - pk_list = queryset.filter(reduce(operator.and_, and_queries)).values_list('pk', flat=True) - return queryset.filter(pk__in=frozenset(pk_list)) - else: - return queryset.filter(reduce(operator.and_, and_queries)).distinct() return queryset @@ -160,7 +163,7 @@ class OrderingFilter(BaseFilterBackend): field.source or field_name for field_name, field in serializer_class().fields.items() if not getattr(field, 'write_only', False) - ] + ] elif valid_fields == '__all__': # View explicitly allows filtering on any model field valid_fields = [field.name for field in queryset.model._meta.fields] @@ -182,6 +185,7 @@ class DjangoObjectPermissionsFilter(BaseFilterBackend): A filter backend that limits results to those where the requesting user has read object level permissions. """ + def __init__(self): assert guardian, 'Using DjangoObjectPermissionsFilter, but django-guardian is not installed'