Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #9749 - Added hook to ModelAdmin for specifying custom ChangeLi…

…sts. Thanks to David Larlet and Eric Florenzano.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@11910 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit ca2d64788d74ea86d4e462d3e58311dc651ee5e0 1 parent a2ef463
Jannis Leidel authored December 18, 2009
10  django/contrib/admin/options.py
@@ -351,6 +351,13 @@ def get_form(self, request, obj=None, **kwargs):
351 351
         defaults.update(kwargs)
352 352
         return modelform_factory(self.model, **defaults)
353 353
 
  354
+    def get_changelist(self, request, **kwargs):
  355
+        """
  356
+        Returns the ChangeList class for use on the changelist page.
  357
+        """
  358
+        from django.contrib.admin.views.main import ChangeList
  359
+        return ChangeList
  360
+
354 361
     def get_changelist_form(self, request, **kwargs):
355 362
         """
356 363
         Returns a Form class for use in the Formset on the changelist page.
@@ -888,7 +895,7 @@ def change_view(self, request, object_id, extra_context=None):
888 895
     @csrf_protect
889 896
     def changelist_view(self, request, extra_context=None):
890 897
         "The 'change list' admin view for this model."
891  
-        from django.contrib.admin.views.main import ChangeList, ERROR_FLAG
  898
+        from django.contrib.admin.views.main import ERROR_FLAG
892 899
         opts = self.model._meta
893 900
         app_label = opts.app_label
894 901
         if not self.has_change_permission(request, None):
@@ -905,6 +912,7 @@ def changelist_view(self, request, extra_context=None):
905 912
             except ValueError:
906 913
                 pass
907 914
 
  915
+        ChangeList = self.get_changelist(request)
908 916
         try:
909 917
             cl = ChangeList(request, self.model, list_display, self.list_display_links, self.list_filter,
910 918
                 self.date_hierarchy, self.search_fields, self.list_select_related, self.list_per_page, self.list_editable, self)
16  tests/regressiontests/admin_views/models.py
@@ -4,6 +4,7 @@
4 4
 from django.core.files.storage import FileSystemStorage
5 5
 from django.db import models
6 6
 from django.contrib import admin
  7
+from django.contrib.admin.views.main import ChangeList
7 8
 from django.core.mail import EmailMessage
8 9
 
9 10
 class Section(models.Model):
@@ -420,6 +421,20 @@ class CategoryInline(admin.StackedInline):
420 421
 class CollectorAdmin(admin.ModelAdmin):
421 422
     inlines = [WidgetInline, DooHickeyInline, GrommetInline, WhatsitInline, FancyDoodadInline, CategoryInline]
422 423
 
  424
+class Gadget(models.Model):
  425
+    name = models.CharField(max_length=100)
  426
+
  427
+    def __unicode__(self):
  428
+        return self.name
  429
+
  430
+class CustomChangeList(ChangeList):
  431
+    def get_query_set(self):
  432
+        return self.root_query_set.filter(pk=9999) # Does not exist
  433
+
  434
+class GadgetAdmin(admin.ModelAdmin):
  435
+    def get_changelist(self, request, **kwargs):
  436
+        return CustomChangeList
  437
+
423 438
 admin.site.register(Article, ArticleAdmin)
424 439
 admin.site.register(CustomArticle, CustomArticleAdmin)
425 440
 admin.site.register(Section, save_as=True, inlines=[ArticleInline])
@@ -443,6 +458,7 @@ class CollectorAdmin(admin.ModelAdmin):
443 458
 admin.site.register(Recommender)
444 459
 admin.site.register(Collector, CollectorAdmin)
445 460
 admin.site.register(Category, CategoryAdmin)
  461
+admin.site.register(Gadget, GadgetAdmin)
446 462
 
447 463
 # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
448 464
 # That way we cover all four cases:
27  tests/regressiontests/admin_views/tests.py
@@ -1203,6 +1203,33 @@ def test_user_message_on_no_action(self):
1203 1203
         self.failUnlessEqual(Subscriber.objects.count(), 2)
1204 1204
 
1205 1205
 
  1206
+class TestCustomChangeList(TestCase):
  1207
+    fixtures = ['admin-views-users.xml']
  1208
+    urlbit = 'admin'
  1209
+
  1210
+    def setUp(self):
  1211
+        result = self.client.login(username='super', password='secret')
  1212
+        self.failUnlessEqual(result, True)
  1213
+
  1214
+    def tearDown(self):
  1215
+        self.client.logout()
  1216
+
  1217
+    def test_custom_changelist(self):
  1218
+        """
  1219
+        Validate that a custom ChangeList class can be used (#9749)
  1220
+        """
  1221
+        # Insert some data
  1222
+        post_data = {"name": u"First Gadget"}
  1223
+        response = self.client.post('/test_admin/%s/admin_views/gadget/add/' % self.urlbit, post_data)
  1224
+        self.failUnlessEqual(response.status_code, 302) # redirect somewhere
  1225
+        # Hit the page once to get messages out of the queue message list
  1226
+        response = self.client.get('/test_admin/%s/admin_views/gadget/' % self.urlbit)
  1227
+        # Ensure that that data is still not visible on the page
  1228
+        response = self.client.get('/test_admin/%s/admin_views/gadget/' % self.urlbit)
  1229
+        self.failUnlessEqual(response.status_code, 200)
  1230
+        self.assertNotContains(response, 'First Gadget')
  1231
+
  1232
+
1206 1233
 class TestInlineNotEditable(TestCase):
1207 1234
     fixtures = ['admin-views-users.xml']
1208 1235
 

0 notes on commit ca2d647

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