Added ModelAdmin.get_search_fields.

This commit is contained in:
Loic Bistuer 2013-08-03 23:15:15 +07:00 committed by Tim Graham
parent a0c58113b9
commit 0bcdcc7eb9
5 changed files with 41 additions and 6 deletions

View File

@ -277,9 +277,10 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):
return "%s__icontains" % field_name return "%s__icontains" % field_name
use_distinct = False use_distinct = False
if self.search_fields and search_term: search_fields = self.get_search_fields(request)
if search_fields and search_term:
orm_lookups = [construct_search(str(search_field)) orm_lookups = [construct_search(str(search_field))
for search_field in self.search_fields] for search_field in search_fields]
for bit in search_term.split(): for bit in search_term.split():
or_queries = [models.Q(**{orm_lookup: bit}) or_queries = [models.Q(**{orm_lookup: bit})
for orm_lookup in orm_lookups] for orm_lookup in orm_lookups]
@ -767,6 +768,13 @@ class ModelAdmin(BaseModelAdmin):
""" """
return self.list_filter return self.list_filter
def get_search_fields(self, request):
"""
Returns a sequence containing the fields to be searched whenever
somebody submits a search query.
"""
return self.search_fields
def get_preserved_filters(self, request): def get_preserved_filters(self, request):
""" """
Returns the preserved filters querystring. Returns the preserved filters querystring.
@ -1243,6 +1251,7 @@ class ModelAdmin(BaseModelAdmin):
list_display = self.get_list_display(request) list_display = self.get_list_display(request)
list_display_links = self.get_list_display_links(request, list_display) list_display_links = self.get_list_display_links(request, list_display)
list_filter = self.get_list_filter(request) list_filter = self.get_list_filter(request)
search_fields = self.get_search_fields(request)
# Check actions to see if any are available on this changelist # Check actions to see if any are available on this changelist
actions = self.get_actions(request) actions = self.get_actions(request)
@ -1254,9 +1263,9 @@ class ModelAdmin(BaseModelAdmin):
try: try:
cl = ChangeList(request, self.model, list_display, cl = ChangeList(request, self.model, list_display,
list_display_links, list_filter, self.date_hierarchy, list_display_links, list_filter, self.date_hierarchy,
self.search_fields, self.list_select_related, search_fields, self.list_select_related, self.list_per_page,
self.list_per_page, self.list_max_show_all, self.list_editable, self.list_max_show_all, self.list_editable, self)
self)
except IncorrectLookupParameters: except IncorrectLookupParameters:
# Wacky lookup parameters were given, so redirect to the main # Wacky lookup parameters were given, so redirect to the main
# changelist page, without parameters, and pass an 'invalid=1' # changelist page, without parameters, and pass an 'invalid=1'

View File

@ -1233,6 +1233,14 @@ templates used by the :class:`ModelAdmin` views:
to return the same kind of sequence type as for the to return the same kind of sequence type as for the
:attr:`~ModelAdmin.list_filter` attribute. :attr:`~ModelAdmin.list_filter` attribute.
.. method:: ModelAdmin.get_search_fields(self, request)
.. versionadded:: 1.7
The ``get_search_fields`` method is given the ``HttpRequest`` and is expected
to return the same kind of sequence type as for the
:attr:`~ModelAdmin.search_fields` attribute.
.. method:: ModelAdmin.get_inline_instances(self, request, obj=None) .. method:: ModelAdmin.get_inline_instances(self, request, obj=None)
.. versionadded:: 1.5 .. versionadded:: 1.5

View File

@ -110,6 +110,9 @@ Minor features
or ``None`` for the key and the custom label as the value. The default blank or ``None`` for the key and the custom label as the value. The default blank
option ``"----------"`` will be omitted in this case. option ``"----------"`` will be omitted in this case.
* The admin's search fields can now be customized per-request thanks to the new
:meth:`django.contrib.admin.ModelAdmin.get_search_fields` method.
Backwards incompatible changes in 1.7 Backwards incompatible changes in 1.7
===================================== =====================================

View File

@ -105,3 +105,10 @@ class DynamicListFilterChildAdmin(admin.ModelAdmin):
my_list_filter.remove('parent') my_list_filter.remove('parent')
return my_list_filter return my_list_filter
class DynamicSearchFieldsChildAdmin(admin.ModelAdmin):
search_fields = ('name',)
def get_search_fields(self, request):
search_fields = super(DynamicSearchFieldsChildAdmin, self).get_search_fields(request)
search_fields += ('age',)
return search_fields

View File

@ -18,7 +18,8 @@ from .admin import (ChildAdmin, QuartetAdmin, BandAdmin, ChordsBandAdmin,
GroupAdmin, ParentAdmin, DynamicListDisplayChildAdmin, GroupAdmin, ParentAdmin, DynamicListDisplayChildAdmin,
DynamicListDisplayLinksChildAdmin, CustomPaginationAdmin, DynamicListDisplayLinksChildAdmin, CustomPaginationAdmin,
FilteredChildAdmin, CustomPaginator, site as custom_site, FilteredChildAdmin, CustomPaginator, site as custom_site,
SwallowAdmin, DynamicListFilterChildAdmin, InvitationAdmin) SwallowAdmin, DynamicListFilterChildAdmin, InvitationAdmin,
DynamicSearchFieldsChildAdmin)
from .models import (Event, Child, Parent, Genre, Band, Musician, Group, from .models import (Event, Child, Parent, Genre, Band, Musician, Group,
Quartet, Membership, ChordsMusician, ChordsBand, Invitation, Swallow, Quartet, Membership, ChordsMusician, ChordsBand, Invitation, Swallow,
UnorderedObject, OrderedObject, CustomIdUser) UnorderedObject, OrderedObject, CustomIdUser)
@ -588,6 +589,13 @@ class ChangeListTests(TestCase):
response = m.changelist_view(request) response = m.changelist_view(request)
self.assertEqual(response.context_data['cl'].list_filter, ('parent', 'name', 'age')) self.assertEqual(response.context_data['cl'].list_filter, ('parent', 'name', 'age'))
def test_dynamic_search_fields(self):
child = self._create_superuser('child')
m = DynamicSearchFieldsChildAdmin(Child, admin.site)
request = self._mocked_authenticated_request('/child/', child)
response = m.changelist_view(request)
self.assertEqual(response.context_data['cl'].search_fields, ('name', 'age'))
def test_pagination_page_range(self): def test_pagination_page_range(self):
""" """
Regression tests for ticket #15653: ensure the number of pages Regression tests for ticket #15653: ensure the number of pages