Commit 35b3158d authored by Loek van Gent's avatar Loek van Gent Committed by Tim Graham
Browse files

Fixed #24417 -- Added ModelAdmin.get_list_select_related()

parent 8d90489f
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -855,6 +855,13 @@ class ModelAdmin(BaseModelAdmin):
        """
        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 @@ class ModelAdmin(BaseModelAdmin):
        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 @@ class ModelAdmin(BaseModelAdmin):
        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:
+11 −1
Original line number Diff line number Diff line
@@ -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
+5 −0
Original line number Diff line number Diff line
@@ -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`
^^^^^^^^^^^^^^^^^^^^^^^^^^

+22 −3
Original line number Diff line number Diff line
@@ -50,9 +50,10 @@ class ChangeListTests(TestCase):
        """
        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,9 +62,10 @@ class ChangeListTests(TestCase):
    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': {}})

@@ -71,12 +73,29 @@ class ChangeListTests(TestCase):
        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