From 3da371625272edb5af43446c32cbc7027223078d Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Thu, 14 May 2009 15:09:33 +0000 Subject: [PATCH] Fixed #10348: ChangeList no longer overwrites a select_related provided by `ModelAdmin.queryset()`. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10782 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/admin/views/main.py | 28 ++++++++++--------- .../admin_changelist/__init__.py | 0 .../admin_changelist/models.py | 9 ++++++ .../regressiontests/admin_changelist/tests.py | 24 ++++++++++++++++ 4 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 tests/regressiontests/admin_changelist/__init__.py create mode 100644 tests/regressiontests/admin_changelist/models.py create mode 100644 tests/regressiontests/admin_changelist/tests.py diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 98e5b9f6d1..df0fd9fab4 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -197,19 +197,21 @@ class ChangeList(object): raise IncorrectLookupParameters # Use select_related() if one of the list_display options is a field - # with a relationship. - if self.list_select_related: - qs = qs.select_related() - else: - for field_name in self.list_display: - try: - f = self.lookup_opts.get_field(field_name) - except models.FieldDoesNotExist: - pass - else: - if isinstance(f.rel, models.ManyToOneRel): - qs = qs.select_related() - break + # with a relationship and the provided queryset doesn't already have + # select_related defined. + if not qs.query.select_related: + if self.list_select_related: + qs = qs.select_related() + else: + for field_name in self.list_display: + try: + f = self.lookup_opts.get_field(field_name) + except models.FieldDoesNotExist: + pass + else: + if isinstance(f.rel, models.ManyToOneRel): + qs = qs.select_related() + break # Set ordering. if self.order_field: diff --git a/tests/regressiontests/admin_changelist/__init__.py b/tests/regressiontests/admin_changelist/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regressiontests/admin_changelist/models.py b/tests/regressiontests/admin_changelist/models.py new file mode 100644 index 0000000000..f030a781e9 --- /dev/null +++ b/tests/regressiontests/admin_changelist/models.py @@ -0,0 +1,9 @@ +from django.db import models +from django.contrib import admin + +class Parent(models.Model): + name = models.CharField(max_length=128) + +class Child(models.Model): + parent = models.ForeignKey(Parent, editable=False) + name = models.CharField(max_length=30, blank=True) \ No newline at end of file diff --git a/tests/regressiontests/admin_changelist/tests.py b/tests/regressiontests/admin_changelist/tests.py new file mode 100644 index 0000000000..2164653b75 --- /dev/null +++ b/tests/regressiontests/admin_changelist/tests.py @@ -0,0 +1,24 @@ +import unittest +from django.contrib import admin +from django.contrib.admin.views.main import ChangeList +from regressiontests.admin_changelist.models import Child + +class ChangeListTests(unittest.TestCase): + def test_select_related_preserved(self): + """ + Regression test for #10348: ChangeList.get_query_set() shouldn't + overwrite a custom select_related provided by ModelAdmin.queryset(). + """ + m = ChildAdmin(Child, admin.site) + cl = ChangeList(MockRequest(), 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, m.list_editable, m) + self.assertEqual(cl.query_set.query.select_related, {'parent': {'name': {}}}) + +class ChildAdmin(admin.ModelAdmin): + list_display = ['name', 'parent'] + def queryset(self, request): + return super(ChildAdmin, self).queryset(request).select_related("parent__name") + +class MockRequest(object): + GET = {}