mirror of https://github.com/django/django.git
Fixed #17646 -- Added a get_list_filter() method to ModelAdmin. Thanks to rasca for the suggestion and to mateusgondim for the patch.
This commit is contained in:
parent
f26b956e80
commit
ae206d78f6
|
@ -665,6 +665,13 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
# Use only the first item in list_display as link
|
# Use only the first item in list_display as link
|
||||||
return list(list_display)[:1]
|
return list(list_display)[:1]
|
||||||
|
|
||||||
|
def get_list_filter(self, request):
|
||||||
|
"""
|
||||||
|
Returns a sequence containing the fields to be displayed as filters in
|
||||||
|
the right sidebar of the changelist page.
|
||||||
|
"""
|
||||||
|
return self.list_filter
|
||||||
|
|
||||||
def construct_change_message(self, request, form, formsets):
|
def construct_change_message(self, request, form, formsets):
|
||||||
"""
|
"""
|
||||||
Construct a change message from a changed object.
|
Construct a change message from a changed object.
|
||||||
|
@ -1192,6 +1199,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)
|
||||||
|
|
||||||
# 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)
|
||||||
|
@ -1202,7 +1210,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
ChangeList = self.get_changelist(request)
|
ChangeList = self.get_changelist(request)
|
||||||
try:
|
try:
|
||||||
cl = ChangeList(request, self.model, list_display,
|
cl = ChangeList(request, self.model, list_display,
|
||||||
list_display_links, self.list_filter, self.date_hierarchy,
|
list_display_links, list_filter, self.date_hierarchy,
|
||||||
self.search_fields, self.list_select_related,
|
self.search_fields, self.list_select_related,
|
||||||
self.list_per_page, self.list_max_show_all, self.list_editable,
|
self.list_per_page, self.list_max_show_all, self.list_editable,
|
||||||
self)
|
self)
|
||||||
|
|
|
@ -570,8 +570,8 @@ subclass::
|
||||||
|
|
||||||
.. image:: _images/users_changelist.png
|
.. image:: _images/users_changelist.png
|
||||||
|
|
||||||
``list_filter`` should be a list of elements, where each element should be
|
``list_filter`` should be a list or tuple of elements, where each element
|
||||||
of one of the following types:
|
should be of one of the following types:
|
||||||
|
|
||||||
* a field name, where the specified field should be either a
|
* a field name, where the specified field should be either a
|
||||||
``BooleanField``, ``CharField``, ``DateField``, ``DateTimeField``,
|
``BooleanField``, ``CharField``, ``DateField``, ``DateTimeField``,
|
||||||
|
@ -1076,6 +1076,14 @@ templates used by the :class:`ModelAdmin` views:
|
||||||
changelist that will be linked to the change view, as described in the
|
changelist that will be linked to the change view, as described in the
|
||||||
:attr:`ModelAdmin.list_display_links` section.
|
:attr:`ModelAdmin.list_display_links` section.
|
||||||
|
|
||||||
|
.. method:: ModelAdmin.get_list_filter(self, request)
|
||||||
|
|
||||||
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
|
The ``get_list_filter`` method is given the ``HttpRequest`` and is expected
|
||||||
|
to return the same kind of sequence type as for the
|
||||||
|
:attr:`~ModelAdmin.list_filter` 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
|
||||||
|
|
|
@ -318,6 +318,9 @@ Django 1.5 also includes several smaller improvements worth noting:
|
||||||
:func:`django.contrib.messages.add_message`. This is useful for generating
|
:func:`django.contrib.messages.add_message`. This is useful for generating
|
||||||
error messages from admin actions.
|
error messages from admin actions.
|
||||||
|
|
||||||
|
* The admin's list filters can now be customized per-request thanks to the new
|
||||||
|
:meth:`django.contrib.admin.ModelAdmin.get_list_filter` method.
|
||||||
|
|
||||||
Backwards incompatible changes in 1.5
|
Backwards incompatible changes in 1.5
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ class ParentAdmin(admin.ModelAdmin):
|
||||||
class ChildAdmin(admin.ModelAdmin):
|
class ChildAdmin(admin.ModelAdmin):
|
||||||
list_display = ['name', 'parent']
|
list_display = ['name', 'parent']
|
||||||
list_per_page = 10
|
list_per_page = 10
|
||||||
|
list_filter = ['parent', 'age']
|
||||||
|
|
||||||
def queryset(self, request):
|
def queryset(self, request):
|
||||||
return super(ChildAdmin, self).queryset(request).select_related("parent__name")
|
return super(ChildAdmin, self).queryset(request).select_related("parent__name")
|
||||||
|
@ -90,3 +91,14 @@ class SwallowAdmin(admin.ModelAdmin):
|
||||||
list_display = ('origin', 'load', 'speed')
|
list_display = ('origin', 'load', 'speed')
|
||||||
|
|
||||||
site.register(Swallow, SwallowAdmin)
|
site.register(Swallow, SwallowAdmin)
|
||||||
|
|
||||||
|
class DynamicListFilterChildAdmin(admin.ModelAdmin):
|
||||||
|
list_filter = ('parent', 'name', 'age')
|
||||||
|
|
||||||
|
def get_list_filter(self, request):
|
||||||
|
my_list_filter = super(DynamicListFilterChildAdmin, self).get_list_filter(request)
|
||||||
|
if request.user.username == 'noparents':
|
||||||
|
my_list_filter = list(my_list_filter)
|
||||||
|
my_list_filter.remove('parent')
|
||||||
|
return my_list_filter
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ 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)
|
SwallowAdmin, DynamicListFilterChildAdmin)
|
||||||
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)
|
UnorderedObject, OrderedObject)
|
||||||
|
@ -541,3 +541,26 @@ class ChangeListTests(TestCase):
|
||||||
check_results_order()
|
check_results_order()
|
||||||
OrderedObjectAdmin.ordering = ['id', 'bool']
|
OrderedObjectAdmin.ordering = ['id', 'bool']
|
||||||
check_results_order(ascending=True)
|
check_results_order(ascending=True)
|
||||||
|
|
||||||
|
def test_dynamic_list_filter(self):
|
||||||
|
"""
|
||||||
|
Regression tests for ticket #17646: dynamic list_filter support.
|
||||||
|
"""
|
||||||
|
parent = Parent.objects.create(name='parent')
|
||||||
|
for i in range(10):
|
||||||
|
Child.objects.create(name='child %s' % i, parent=parent)
|
||||||
|
|
||||||
|
user_noparents = self._create_superuser('noparents')
|
||||||
|
user_parents = self._create_superuser('parents')
|
||||||
|
|
||||||
|
# Test with user 'noparents'
|
||||||
|
m = DynamicListFilterChildAdmin(Child, admin.site)
|
||||||
|
request = self._mocked_authenticated_request('/child/', user_noparents)
|
||||||
|
response = m.changelist_view(request)
|
||||||
|
self.assertEqual(response.context_data['cl'].list_filter, ['name', 'age'])
|
||||||
|
|
||||||
|
# Test with user 'parents'
|
||||||
|
m = DynamicListFilterChildAdmin(Child, admin.site)
|
||||||
|
request = self._mocked_authenticated_request('/child/', user_parents)
|
||||||
|
response = m.changelist_view(request)
|
||||||
|
self.assertEqual(response.context_data['cl'].list_filter, ('parent', 'name', 'age'))
|
||||||
|
|
Loading…
Reference in New Issue