Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.0.X] Fixed #10516 -- Corrected admin search when the search_fields…

… definition contains multiple fields on the same base model. Thanks to Zain Memon

Merge of r10684 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@10719 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 41ba8e7ca6c0cd089cf196207ec136e815721399 1 parent 7bcbc99
Russell Keith-Magee authored May 08, 2009
9  django/contrib/admin/views/main.py
@@ -190,7 +190,7 @@ def get_query_set(self):
190 190
         # Naked except! Because we don't have any other way of validating "params".
191 191
         # They might be invalid if the keyword arguments are incorrect, or if the
192 192
         # values are not in the correct type, so we might get FieldError, ValueError,
193  
-        # ValicationError, or ? from a custom field that raises yet something else 
  193
+        # ValicationError, or ? from a custom field that raises yet something else
194 194
         # when handed impossible data.
195 195
         except:
196 196
             raise IncorrectLookupParameters
@@ -227,11 +227,8 @@ def construct_search(field_name):
227 227
 
228 228
         if self.search_fields and self.query:
229 229
             for bit in self.query.split():
230  
-                or_queries = [models.Q(**{construct_search(field_name): bit}) for field_name in self.search_fields]
231  
-                other_qs = QuerySet(self.model)
232  
-                other_qs.dup_select_related(qs)
233  
-                other_qs = other_qs.filter(reduce(operator.or_, or_queries))
234  
-                qs = qs & other_qs
  230
+                or_queries = [models.Q(**{construct_search(str(field_name)): bit}) for field_name in self.search_fields]
  231
+                qs = qs.filter(reduce(operator.or_, or_queries))
235 232
             for field_name in self.search_fields:
236 233
                 if '__' in field_name:
237 234
                     qs = qs.distinct()
107  tests/regressiontests/admin_views/fixtures/multiple-child-classes.json
... ...
@@ -0,0 +1,107 @@
  1
+[
  2
+    {
  3
+        "pk": 1,
  4
+         "model": "admin_views.title",
  5
+         "fields":
  6
+        {
  7
+        }
  8
+    },
  9
+
  10
+    {
  11
+        "pk": 2,
  12
+         "model": "admin_views.title",
  13
+         "fields":
  14
+        {
  15
+        }
  16
+    },
  17
+
  18
+    {
  19
+        "pk": 3,
  20
+         "model": "admin_views.title",
  21
+         "fields":
  22
+        {
  23
+        }
  24
+    },
  25
+
  26
+    {
  27
+        "pk": 4,
  28
+         "model": "admin_views.title",
  29
+         "fields":
  30
+        {
  31
+        }
  32
+    },
  33
+
  34
+    {
  35
+        "pk": 1,
  36
+         "model": "admin_views.titletranslation",
  37
+         "fields":
  38
+        {
  39
+            "text": "Bar",
  40
+             "title": 1
  41
+        }
  42
+    },
  43
+
  44
+    {
  45
+        "pk": 2,
  46
+         "model": "admin_views.titletranslation",
  47
+         "fields":
  48
+        {
  49
+            "text": "Foo",
  50
+             "title": 2
  51
+        }
  52
+    },
  53
+
  54
+    {
  55
+        "pk": 3,
  56
+         "model": "admin_views.titletranslation",
  57
+         "fields":
  58
+        {
  59
+            "text": "Few",
  60
+             "title": 3
  61
+        }
  62
+    },
  63
+
  64
+    {
  65
+        "pk": 4,
  66
+         "model": "admin_views.titletranslation",
  67
+         "fields":
  68
+        {
  69
+            "text": "Bas",
  70
+             "title": 4
  71
+        }
  72
+    },
  73
+
  74
+    {
  75
+        "pk": 1,
  76
+         "model": "admin_views.recommender",
  77
+         "fields":
  78
+        {
  79
+        }
  80
+    },
  81
+
  82
+    {
  83
+        "pk": 4,
  84
+         "model": "admin_views.recommender",
  85
+         "fields":
  86
+        {
  87
+        }
  88
+    },
  89
+
  90
+    {
  91
+        "pk": 2,
  92
+         "model": "admin_views.recommendation",
  93
+         "fields":
  94
+        {
  95
+            "recommender": 1
  96
+        }
  97
+    },
  98
+
  99
+    {
  100
+        "pk": 3,
  101
+         "model": "admin_views.recommendation",
  102
+         "fields":
  103
+        {
  104
+            "recommender": 4
  105
+        }
  106
+    }
  107
+]
20  tests/regressiontests/admin_views/models.py
@@ -238,6 +238,24 @@ class GalleryAdmin(admin.ModelAdmin):
238 238
 class PictureAdmin(admin.ModelAdmin):
239 239
     pass
240 240
 
  241
+# a base class for Recommender and Recommendation
  242
+class Title(models.Model):
  243
+    pass
  244
+
  245
+class TitleTranslation(models.Model):
  246
+    title = models.ForeignKey(Title)
  247
+    text = models.CharField(max_length=100)
  248
+
  249
+class Recommender(Title):
  250
+    pass
  251
+
  252
+class Recommendation(Title):
  253
+    recommender = models.ForeignKey(Recommender)
  254
+
  255
+class RecommendationAdmin(admin.ModelAdmin):
  256
+    search_fields = ('titletranslation__text', 'recommender__titletranslation__text',)
  257
+
  258
+
241 259
 admin.site.register(Article, ArticleAdmin)
242 260
 admin.site.register(CustomArticle, CustomArticleAdmin)
243 261
 admin.site.register(Section, save_as=True, inlines=[ArticleInline])
@@ -250,6 +268,8 @@ class PictureAdmin(admin.ModelAdmin):
250 268
 admin.site.register(Fabric, FabricAdmin)
251 269
 admin.site.register(Gallery, GalleryAdmin)
252 270
 admin.site.register(Picture, PictureAdmin)
  271
+admin.site.register(Recommendation, RecommendationAdmin)
  272
+admin.site.register(Recommender)
253 273
 
254 274
 # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
255 275
 # That way we cover all four cases:
15  tests/regressiontests/admin_views/tests.py
@@ -816,6 +816,21 @@ def testUnicodeDelete(self):
816 816
         response = self.client.post('/test_admin/admin/admin_views/book/1/delete/', delete_dict)
817 817
         self.assertRedirects(response, '/test_admin/admin/admin_views/book/')
818 818
 
  819
+class AdminSearchTest(TestCase):
  820
+    fixtures = ['admin-views-users','multiple-child-classes']
  821
+
  822
+    def setUp(self):
  823
+        self.client.login(username='super', password='secret')
  824
+
  825
+    def tearDown(self):
  826
+        self.client.logout()
  827
+
  828
+    def test_search_on_sibling_models(self):
  829
+        "Check that a search that mentions sibling models"
  830
+        response = self.client.get('/test_admin/admin/admin_views/recommendation/', data={'q':'bar'})
  831
+        # confirm the search returned 1 object
  832
+        self.assertContains(response, "\n1 recommendation\n")
  833
+
819 834
 class AdminInheritedInlinesTest(TestCase):
820 835
     fixtures = ['admin-views-users.xml',]
821 836
 

0 notes on commit 41ba8e7

Please sign in to comment.
Something went wrong with that request. Please try again.