diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 9b5703f63a..35afd6284f 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -190,7 +190,7 @@ class ChangeList(object): # Naked except! Because we don't have any other way of validating "params". # They might be invalid if the keyword arguments are incorrect, or if the # values are not in the correct type, so we might get FieldError, ValueError, - # ValicationError, or ? from a custom field that raises yet something else + # ValicationError, or ? from a custom field that raises yet something else # when handed impossible data. except: raise IncorrectLookupParameters @@ -227,11 +227,8 @@ class ChangeList(object): if self.search_fields and self.query: for bit in self.query.split(): - or_queries = [models.Q(**{construct_search(field_name): bit}) for field_name in self.search_fields] - other_qs = QuerySet(self.model) - other_qs.dup_select_related(qs) - other_qs = other_qs.filter(reduce(operator.or_, or_queries)) - qs = qs & other_qs + or_queries = [models.Q(**{construct_search(str(field_name)): bit}) for field_name in self.search_fields] + qs = qs.filter(reduce(operator.or_, or_queries)) for field_name in self.search_fields: if '__' in field_name: qs = qs.distinct() diff --git a/tests/regressiontests/admin_views/fixtures/multiple-child-classes.json b/tests/regressiontests/admin_views/fixtures/multiple-child-classes.json new file mode 100644 index 0000000000..5cadf4c1c5 --- /dev/null +++ b/tests/regressiontests/admin_views/fixtures/multiple-child-classes.json @@ -0,0 +1,107 @@ +[ + { + "pk": 1, + "model": "admin_views.title", + "fields": + { + } + }, + + { + "pk": 2, + "model": "admin_views.title", + "fields": + { + } + }, + + { + "pk": 3, + "model": "admin_views.title", + "fields": + { + } + }, + + { + "pk": 4, + "model": "admin_views.title", + "fields": + { + } + }, + + { + "pk": 1, + "model": "admin_views.titletranslation", + "fields": + { + "text": "Bar", + "title": 1 + } + }, + + { + "pk": 2, + "model": "admin_views.titletranslation", + "fields": + { + "text": "Foo", + "title": 2 + } + }, + + { + "pk": 3, + "model": "admin_views.titletranslation", + "fields": + { + "text": "Few", + "title": 3 + } + }, + + { + "pk": 4, + "model": "admin_views.titletranslation", + "fields": + { + "text": "Bas", + "title": 4 + } + }, + + { + "pk": 1, + "model": "admin_views.recommender", + "fields": + { + } + }, + + { + "pk": 4, + "model": "admin_views.recommender", + "fields": + { + } + }, + + { + "pk": 2, + "model": "admin_views.recommendation", + "fields": + { + "recommender": 1 + } + }, + + { + "pk": 3, + "model": "admin_views.recommendation", + "fields": + { + "recommender": 4 + } + } +] \ No newline at end of file diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py index 7e600ede53..b8e931597a 100644 --- a/tests/regressiontests/admin_views/models.py +++ b/tests/regressiontests/admin_views/models.py @@ -238,6 +238,24 @@ class GalleryAdmin(admin.ModelAdmin): class PictureAdmin(admin.ModelAdmin): pass +# a base class for Recommender and Recommendation +class Title(models.Model): + pass + +class TitleTranslation(models.Model): + title = models.ForeignKey(Title) + text = models.CharField(max_length=100) + +class Recommender(Title): + pass + +class Recommendation(Title): + recommender = models.ForeignKey(Recommender) + +class RecommendationAdmin(admin.ModelAdmin): + search_fields = ('titletranslation__text', 'recommender__titletranslation__text',) + + admin.site.register(Article, ArticleAdmin) admin.site.register(CustomArticle, CustomArticleAdmin) admin.site.register(Section, save_as=True, inlines=[ArticleInline]) @@ -250,6 +268,8 @@ admin.site.register(EmptyModel, EmptyModelAdmin) admin.site.register(Fabric, FabricAdmin) admin.site.register(Gallery, GalleryAdmin) admin.site.register(Picture, PictureAdmin) +admin.site.register(Recommendation, RecommendationAdmin) +admin.site.register(Recommender) # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2. # That way we cover all four cases: diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index 4aafa1947f..f11b241a10 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -816,6 +816,21 @@ class AdminViewUnicodeTest(TestCase): response = self.client.post('/test_admin/admin/admin_views/book/1/delete/', delete_dict) self.assertRedirects(response, '/test_admin/admin/admin_views/book/') +class AdminSearchTest(TestCase): + fixtures = ['admin-views-users','multiple-child-classes'] + + def setUp(self): + self.client.login(username='super', password='secret') + + def tearDown(self): + self.client.logout() + + def test_search_on_sibling_models(self): + "Check that a search that mentions sibling models" + response = self.client.get('/test_admin/admin/admin_views/recommendation/', data={'q':'bar'}) + # confirm the search returned 1 object + self.assertContains(response, "\n1 recommendation\n") + class AdminInheritedInlinesTest(TestCase): fixtures = ['admin-views-users.xml',]