Merge pull request #1432 from loic/modeladmin.get_search_results

Moved get_search_results from BaseModelAdmin to ModelAdmin.
This commit is contained in:
Tim Graham 2013-08-04 04:17:34 -07:00
commit 59f58bf731
1 changed files with 33 additions and 30 deletions

View File

@ -264,35 +264,6 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):
""" """
return self.prepopulated_fields 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
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_queryset(self, request): def get_queryset(self, request):
""" """
Returns a QuerySet of all model instances that can be edited by the Returns a QuerySet of all model instances that can be edited by the
@ -775,11 +746,43 @@ class ModelAdmin(BaseModelAdmin):
""" """
return self.search_fields return self.search_fields
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): def get_preserved_filters(self, request):
""" """
Returns the preserved filters querystring. Returns the preserved filters querystring.
""" """
match = request.resolver_match match = request.resolver_match
if self.preserve_filters and match: if self.preserve_filters and match:
opts = self.model._meta opts = self.model._meta