Permalink
Browse files

Fixed #24417 -- Added ModelAdmin.get_list_select_related()

  • Loading branch information...
1 parent 8d90489 commit 35b3158d52a5fe51d3b52aec1109a30a73c5abe9 @gannetson gannetson committed with timgraham Mar 16, 2015
Showing with 47 additions and 5 deletions.
  1. +9 −1 django/contrib/admin/options.py
  2. +11 −1 docs/ref/contrib/admin/index.txt
  3. +5 −0 docs/releases/1.9.txt
  4. +22 −3 tests/admin_changelist/tests.py
@@ -855,6 +855,13 @@ def get_list_filter(self, request):
"""
return self.list_filter
+ def get_list_select_related(self, request):
+ """
+ Returns a list of fields to add to the select_related() part of the
+ changelist items query.
+ """
+ return self.list_select_related
+
def get_search_fields(self, request):
"""
Returns a sequence containing the fields to be searched whenever
@@ -1433,6 +1440,7 @@ def changelist_view(self, request, extra_context=None):
list_display_links = self.get_list_display_links(request, list_display)
list_filter = self.get_list_filter(request)
search_fields = self.get_search_fields(request)
+ list_select_related = self.get_list_select_related(request)
# Check actions to see if any are available on this changelist
actions = self.get_actions(request)
@@ -1444,7 +1452,7 @@ def changelist_view(self, request, extra_context=None):
try:
cl = ChangeList(request, self.model, list_display,
list_display_links, list_filter, self.date_hierarchy,
- search_fields, self.list_select_related, self.list_per_page,
+ search_fields, list_select_related, self.list_per_page,
self.list_max_show_all, self.list_editable, self)
except IncorrectLookupParameters:
@@ -920,6 +920,9 @@ subclass::
will call ``select_related('author', 'category')``.
+ If you need to specify a dynamic value based on the request, you can
+ implement a :meth:`~ModelAdmin.get_list_select_related` method.
+
.. attribute:: ModelAdmin.ordering
Set ``ordering`` to specify how lists of objects should be ordered in the
@@ -932,7 +935,6 @@ subclass::
If you need to specify a dynamic order (for example depending on user or
language) you can implement a :meth:`~ModelAdmin.get_ordering` method.
-
.. attribute:: ModelAdmin.paginator
The paginator class to be used for pagination. By default,
@@ -1366,6 +1368,14 @@ templates used by the :class:`ModelAdmin` views:
to return the same kind of sequence type as for the
:attr:`~ModelAdmin.list_filter` attribute.
+.. method:: ModelAdmin.get_list_select_related(request)
+
+ .. versionadded:: 1.9
+
+ The ``get_list_select_related`` method is given the ``HttpRequest`` and
+ should return a boolean or list as :attr:`ModelAdmin.list_select_related`
+ does.
+
.. method:: ModelAdmin.get_search_fields(request)
The ``get_search_fields`` method is given the ``HttpRequest`` and is expected
View
@@ -43,6 +43,11 @@ Minor features
the old URL still redirects to the new one for backwards compatibility, but
it may be removed in a future version.
+* :meth:`ModelAdmin.get_list_select_related()
+ <django.contrib.admin.ModelAdmin.get_list_select_related>` was added to allow
+ changing the ``select_related()`` values used in the admin's changelist query
+ based on the request.
+
:mod:`django.contrib.auth`
^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,9 +50,10 @@ def test_select_related_preserved(self):
"""
m = ChildAdmin(Child, admin.site)
request = self.factory.get('/child/')
+ list_select_related = m.get_list_select_related(request)
cl = ChangeList(request, Child, m.list_display, m.list_display_links,
m.list_filter, m.date_hierarchy, m.search_fields,
- m.list_select_related, m.list_per_page,
+ list_select_related, m.list_per_page,
m.list_max_show_all, m.list_editable, m)
self.assertEqual(cl.queryset.query.select_related, {
'parent': {'name': {}}
@@ -61,22 +62,40 @@ def test_select_related_preserved(self):
def test_select_related_as_tuple(self):
ia = InvitationAdmin(Invitation, admin.site)
request = self.factory.get('/invitation/')
+ list_select_related = ia.get_list_select_related(request)
cl = ChangeList(request, Child, ia.list_display, ia.list_display_links,
ia.list_filter, ia.date_hierarchy, ia.search_fields,
- ia.list_select_related, ia.list_per_page,
+ list_select_related, ia.list_per_page,
ia.list_max_show_all, ia.list_editable, ia)
self.assertEqual(cl.queryset.query.select_related, {'player': {}})
def test_select_related_as_empty_tuple(self):
ia = InvitationAdmin(Invitation, admin.site)
ia.list_select_related = ()
request = self.factory.get('/invitation/')
+ list_select_related = ia.get_list_select_related(request)
cl = ChangeList(request, Child, ia.list_display, ia.list_display_links,
ia.list_filter, ia.date_hierarchy, ia.search_fields,
- ia.list_select_related, ia.list_per_page,
+ list_select_related, ia.list_per_page,
ia.list_max_show_all, ia.list_editable, ia)
self.assertEqual(cl.queryset.query.select_related, False)
+ def test_get_select_related_custom_method(self):
+ class GetListSelectRelatedAdmin(admin.ModelAdmin):
+ list_display = ('band', 'player')
+
+ def get_list_select_related(self, request):
+ return ('band', 'player')
+
+ ia = GetListSelectRelatedAdmin(Invitation, admin.site)
+ request = self.factory.get('/invitation/')
+ list_select_related = ia.get_list_select_related(request)
+ cl = ChangeList(request, Child, ia.list_display, ia.list_display_links,
+ ia.list_filter, ia.date_hierarchy, ia.search_fields,
+ list_select_related, ia.list_per_page,
+ ia.list_max_show_all, ia.list_editable, ia)
+ self.assertEqual(cl.queryset.query.select_related, {'player': {}, 'band': {}})
+
def test_result_list_empty_changelist_value(self):
"""
Regression test for #14982: EMPTY_CHANGELIST_VALUE should be honored

0 comments on commit 35b3158

Please sign in to comment.