Commits

ja...@bcc190cf-cafb-0310-a4f2-bffc1f526a37  committed 1bfc9b5

Fixed #9122: generic inline formsets now respect exclude and max_num. Thanks, Alex Robbins.

  • Participants
  • Parent commits 18cc76e

Comments (0)

Files changed (4)

     ricardojbarrios@gmail.com
     Mike Richardson
     Matt Riggott
+    Alex Robbins <alexander.j.robbins@gmail.com>
     Henrique Romano <onaiort@gmail.com>
     Armin Ronacher
     Daniel Roseman <http://roseman.org.uk/>

File django/contrib/contenttypes/generic.py

             "can_delete": True,
             "can_order": False,
             "fields": fields,
+            "max_num": self.max_num,
+            "exclude": self.exclude
         }
         return generic_inlineformset_factory(self.model, **defaults)
 

File tests/regressiontests/generic_inline_admin/models.py

 
 class MediaInline(generic.GenericTabularInline):
     model = Media
-    extra = 1
     
 class EpisodeAdmin(admin.ModelAdmin):
     inlines = [
         MediaInline,
     ]
+admin.site.register(Episode, EpisodeAdmin)
 
-admin.site.register(Episode, EpisodeAdmin)
+#
+# These models let us test the different GenericInline settings at
+# different urls in the admin site.
+#
+
+#
+# Generic inline with extra = 0
+#
+
+class EpisodeExtra(Episode):
+    pass
+
+class MediaExtraInline(generic.GenericTabularInline):
+    model = Media
+    extra = 0
+
+admin.site.register(EpisodeExtra, inlines=[MediaExtraInline])
+
+#
+# Generic inline with extra and max_num
+#
+
+class EpisodeMaxNum(Episode):
+    pass
+
+class MediaMaxNumInline(generic.GenericTabularInline):
+    model = Media
+    extra = 5
+    max_num = 2
+    
+admin.site.register(EpisodeMaxNum, inlines=[MediaMaxNumInline])
+
+#
+# Generic inline with exclude
+#
+
+class EpisodeExclude(Episode):
+    pass
+
+class MediaExcludeInline(generic.GenericTabularInline):
+    model = Media
+    exclude = ['url']
+
+admin.site.register(EpisodeExclude, inlines=[MediaExcludeInline])
+

File tests/regressiontests/generic_inline_admin/tests.py

 from django.contrib.contenttypes.generic import generic_inlineformset_factory
 
 # local test models
-from models import Episode, Media
+from models import Episode, EpisodeExtra, EpisodeMaxNum, EpisodeExclude, Media
 
 class GenericAdminViewTest(TestCase):
     fixtures = ['users.xml']
         # Regression test for #10522.
         inline_formset = generic_inlineformset_factory(Media,
             exclude=('url',))
+
+class GenericInlineAdminParametersTest(TestCase):
+    fixtures = ['users.xml']
+
+    def setUp(self):
+        self.client.login(username='super', password='secret')
+        
+        # Can't load content via a fixture (since the GenericForeignKey
+        # relies on content type IDs, which will vary depending on what
+        # other tests have been run), thus we do it here.
+        test_classes = [
+            Episode,
+            EpisodeExtra,
+            EpisodeMaxNum,
+            EpisodeExclude,
+        ]
+        for klass in test_classes:
+            e = klass.objects.create(name='This Week in Django')
+            m = Media(content_object=e, url='http://example.com/podcast.mp3')
+            m.save()
+    
+    def tearDown(self):
+        self.client.logout()
+
+    def testNoParam(self):
+        """
+        With one initial form, extra (default) at 3, there should be 4 forms.
+        """
+        response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episode/1/')
+        formset = response.context['inline_admin_formsets'][0].formset
+        self.assertEqual(formset.total_form_count(), 4)
+        self.assertEqual(formset.initial_form_count(), 1)
+
+    def testExtraParam(self):
+        """
+        With extra=0, there should be one form.
+        """
+        response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episodeextra/2/')
+        formset = response.context['inline_admin_formsets'][0].formset
+        self.assertEqual(formset.total_form_count(), 1)
+        self.assertEqual(formset.initial_form_count(), 1)
+
+    def testMaxNumParam(self):
+        """
+        With extra=5 and max_num=2, there should be only 2 forms.
+        """
+        inline_form_data = '<input type="hidden" name="generic_inline_admin-media-content_type-object_id-TOTAL_FORMS" value="2" id="id_generic_inline_admin-media-content_type-object_id-TOTAL_FORMS" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-INITIAL_FORMS" value="1" id="id_generic_inline_admin-media-content_type-object_id-INITIAL_FORMS" />'
+        response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episodemaxnum/3/')
+        formset = response.context['inline_admin_formsets'][0].formset
+        self.assertEqual(formset.total_form_count(), 2)
+        self.assertEqual(formset.initial_form_count(), 1)
+
+    def testExcludeParam(self):
+        """
+        Generic inline formsets should respect include.
+        """
+        response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episodeexclude/4/')
+        formset = response.context['inline_admin_formsets'][0].formset
+        self.failIf('url' in formset.forms[0], 'The formset has excluded "url" field.')