Code

Ticket #10348: 10348-introspect-qs.diff

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

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

Line 
1Index: django/contrib/admin/views/main.py
2===================================================================
3--- django/contrib/admin/views/main.py  (revision 10585)
4+++ django/contrib/admin/views/main.py  (working copy)
5@@ -197,19 +197,22 @@
6             raise IncorrectLookupParameters
7 
8         # Use select_related() if one of the list_display options is a field
9-        # with a relationship.
10-        if self.list_select_related:
11-            qs = qs.select_related()
12-        else:
13-            for field_name in self.list_display:
14-                try:
15-                    f = self.lookup_opts.get_field(field_name)
16-                except models.FieldDoesNotExist:
17-                    pass
18-                else:
19-                    if isinstance(f.rel, models.ManyToOneRel):
20-                        qs = qs.select_related()
21-                        break
22+        # with a relationship, but only if the queryset doesn't already have
23+        # select_related set.  (If ModelAdmin.queryset was overridden with
24+        # different select_related() paramaters we want to preserve them.)
25+        if not qs.query.select_related:
26+            if self.list_select_related:
27+                qs = qs.select_related()
28+            else:
29+                for field_name in self.list_display:
30+                    try:
31+                        f = self.lookup_opts.get_field(field_name)
32+                    except models.FieldDoesNotExist:
33+                        pass
34+                    else:
35+                        if isinstance(f.rel, models.ManyToOneRel):
36+                            qs = qs.select_related()
37+                            break
38 
39         # Set ordering.
40         if self.order_field:
41Index: tests/regressiontests/admin_views/tests.py
42===================================================================
43--- tests/regressiontests/admin_views/tests.py  (revision 10585)
44+++ tests/regressiontests/admin_views/tests.py  (working copy)
45@@ -11,9 +11,10 @@
46 from django.contrib.admin.util import quote
47 from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
48 from django.utils.html import escape
49+from django.contrib.admin.views.main import ChangeList
50 
51 # local test models
52-from models import Article, CustomArticle, Section, ModelWithStringPrimaryKey, Person, Persona, FooAccount, BarAccount, Subscriber, ExternalSubscriber, Podcast, EmptyModel
53+from models import Article, CustomArticle, Section, ModelWithStringPrimaryKey, Person, Persona, FooAccount, BarAccount, Subscriber, ExternalSubscriber, Podcast, EmptyModel, ChildAdmin, Child
54 
55 try:
56     set
57@@ -1062,3 +1063,15 @@
58                 self.assertEqual(response.status_code, 200)
59             else:
60                 self.assertEqual(response.status_code, 404)
61+
62+    def test_select_related_preserved(self):
63+        from django.contrib.admin import site
64+        m = ChildAdmin(Child, site)
65+        class MockRequest(object):
66+            GET = {}
67+        cl = ChangeList(MockRequest(), Child, m.list_display, m.list_display_links,
68+                m.list_filter,m.date_hierarchy, m.search_fields,
69+                m.list_select_related, m.list_per_page, m.list_editable,
70+                m)
71+        self.assertEqual(cl.query_set.query.select_related, {'parent': {'name': {}}})
72+
73Index: tests/regressiontests/admin_views/models.py
74===================================================================
75--- tests/regressiontests/admin_views/models.py (revision 10585)
76+++ tests/regressiontests/admin_views/models.py (working copy)
77@@ -280,6 +280,12 @@
78     model = Parent
79     inlines = [ChildInline]
80 
81+class ChildAdmin(admin.ModelAdmin):
82+    model = Child
83+    list_display = ['name', 'parent']
84+    def queryset(self, request):
85+        return super(ChildAdmin, self).queryset(request).select_related("parent__name")
86+
87 class EmptyModel(models.Model):
88     def __unicode__(self):
89         return "Primary key = %s" % self.id