From 9053c6da5fcfe98c05527591f9fd785223eb354a Mon Sep 17 00:00:00 2001
From: Loic Bistuer <loic.bistuer@sixmedia.com>
Date: Sun, 4 Aug 2013 17:18:17 +0700
Subject: [PATCH] [1.6.x] Moved get_search_results from BaseModelAdmin to
 ModelAdmin.

Refs #15961.

Backport of 470a9bb22d from master.
---
 django/contrib/admin/options.py | 62 ++++++++++++++++++---------------
 1 file changed, 33 insertions(+), 29 deletions(-)

diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 131c0ad886..b2f90ca4d9 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -264,34 +264,6 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):
         """
         return self.prepopulated_fields
 
-    def get_search_results(self, request, queryset, search_term):
-        # Apply keyword searches.
-        def construct_search(field_name):
-            if field_name.startswith('^'):
-                return "%s__istartswith" % field_name[1:]
-            elif field_name.startswith('='):
-                return "%s__iexact" % field_name[1:]
-            elif field_name.startswith('@'):
-                return "%s__search" % field_name[1:]
-            else:
-                return "%s__icontains" % field_name
-
-        use_distinct = False
-        if self.search_fields and search_term:
-            orm_lookups = [construct_search(str(search_field))
-                           for search_field in self.search_fields]
-            for bit in search_term.split():
-                or_queries = [models.Q(**{orm_lookup: bit})
-                              for orm_lookup in orm_lookups]
-                queryset = queryset.filter(reduce(operator.or_, or_queries))
-            if not use_distinct:
-                for search_spec in orm_lookups:
-                    if lookup_needs_distinct(self.opts, search_spec):
-                        use_distinct = True
-                        break
-
-        return queryset, use_distinct
-
     def get_queryset(self, request):
         """
         Returns a QuerySet of all model instances that can be edited by the
@@ -767,11 +739,43 @@ class ModelAdmin(BaseModelAdmin):
         """
         return self.list_filter
 
+    def get_search_results(self, request, queryset, search_term):
+        """
+        Returns a tuple containing a queryset to implement the search,
+        and a boolean indicating if the results may contain duplicates.
+        """
+        # Apply keyword searches.
+        def construct_search(field_name):
+            if field_name.startswith('^'):
+                return "%s__istartswith" % field_name[1:]
+            elif field_name.startswith('='):
+                return "%s__iexact" % field_name[1:]
+            elif field_name.startswith('@'):
+                return "%s__search" % field_name[1:]
+            else:
+                return "%s__icontains" % field_name
+
+        use_distinct = False
+        search_fields = self.get_search_fields(request)
+        if search_fields and search_term:
+            orm_lookups = [construct_search(str(search_field))
+                           for search_field in search_fields]
+            for bit in search_term.split():
+                or_queries = [models.Q(**{orm_lookup: bit})
+                              for orm_lookup in orm_lookups]
+                queryset = queryset.filter(reduce(operator.or_, or_queries))
+            if not use_distinct:
+                for search_spec in orm_lookups:
+                    if lookup_needs_distinct(self.opts, search_spec):
+                        use_distinct = True
+                        break
+
+        return queryset, use_distinct
+
     def get_preserved_filters(self, request):
         """
         Returns the preserved filters querystring.
         """
-
         match = request.resolver_match
         if self.preserve_filters and match:
             opts = self.model._meta