Ticket #10348: 10348-introspect-qs.diff

File 10348-introspect-qs.diff, 3.8 KB (added by mmarshall, 6 years ago)

Don't change select_related if it's already truthy. (with tests)

  • django/contrib/admin/views/main.py

     
    197197            raise IncorrectLookupParameters
    198198
    199199        # Use select_related() if one of the list_display options is a field
    200         # with a relationship.
    201         if self.list_select_related:
    202             qs = qs.select_related()
    203         else:
    204             for field_name in self.list_display:
    205                 try:
    206                     f = self.lookup_opts.get_field(field_name)
    207                 except models.FieldDoesNotExist:
    208                     pass
    209                 else:
    210                     if isinstance(f.rel, models.ManyToOneRel):
    211                         qs = qs.select_related()
    212                         break
     200        # with a relationship, but only if the queryset doesn't already have
     201        # select_related set.  (If ModelAdmin.queryset was overridden with
     202        # different select_related() paramaters we want to preserve them.)
     203        if not qs.query.select_related:
     204            if self.list_select_related:
     205                qs = qs.select_related()
     206            else:
     207                for field_name in self.list_display:
     208                    try:
     209                        f = self.lookup_opts.get_field(field_name)
     210                    except models.FieldDoesNotExist:
     211                        pass
     212                    else:
     213                        if isinstance(f.rel, models.ManyToOneRel):
     214                            qs = qs.select_related()
     215                            break
    213216
    214217        # Set ordering.
    215218        if self.order_field:
  • tests/regressiontests/admin_views/tests.py

     
    1111from django.contrib.admin.util import quote
    1212from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
    1313from django.utils.html import escape
     14from django.contrib.admin.views.main import ChangeList
    1415
    1516# local test models
    16 from models import Article, CustomArticle, Section, ModelWithStringPrimaryKey, Person, Persona, FooAccount, BarAccount, Subscriber, ExternalSubscriber, Podcast, EmptyModel
     17from models import Article, CustomArticle, Section, ModelWithStringPrimaryKey, Person, Persona, FooAccount, BarAccount, Subscriber, ExternalSubscriber, Podcast, EmptyModel, ChildAdmin, Child
    1718
    1819try:
    1920    set
     
    10621063                self.assertEqual(response.status_code, 200)
    10631064            else:
    10641065                self.assertEqual(response.status_code, 404)
     1066
     1067    def test_select_related_preserved(self):
     1068        from django.contrib.admin import site
     1069        m = ChildAdmin(Child, site)
     1070        class MockRequest(object):
     1071            GET = {}
     1072        cl = ChangeList(MockRequest(), Child, m.list_display, m.list_display_links,
     1073                m.list_filter,m.date_hierarchy, m.search_fields,
     1074                m.list_select_related, m.list_per_page, m.list_editable,
     1075                m)
     1076        self.assertEqual(cl.query_set.query.select_related, {'parent': {'name': {}}})
     1077
  • tests/regressiontests/admin_views/models.py

     
    280280    model = Parent
    281281    inlines = [ChildInline]
    282282
     283class ChildAdmin(admin.ModelAdmin):
     284    model = Child
     285    list_display = ['name', 'parent']
     286    def queryset(self, request):
     287        return super(ChildAdmin, self).queryset(request).select_related("parent__name")
     288
    283289class EmptyModel(models.Model):
    284290    def __unicode__(self):
    285291        return "Primary key = %s" % self.id
Back to Top