Commit 01669a35 authored by Jacob Kaplan-Moss's avatar Jacob Kaplan-Moss
Browse files

[1.0.X] Fixed #9122: generic inline formsets now respect exclude and max_num....

[1.0.X] Fixed #9122: generic inline formsets now respect exclude and max_num. Thanks, Alex Robbins. Backport of [10586] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@10587 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 681a26ca
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -344,6 +344,7 @@ answer newbie questions, and generally made Django that much better:
    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/>
+2 −0
Original line number Diff line number Diff line
@@ -389,6 +389,8 @@ class GenericInlineModelAdmin(InlineModelAdmin):
            "can_delete": True,
            "can_order": False,
            "fields": fields,
            "max_num": self.max_num,
            "exclude": self.exclude
        }
        return generic_inlineformset_factory(self.model, **defaults)

+46 −2
Original line number Diff line number Diff line
@@ -20,11 +20,55 @@ class Media(models.Model):

class MediaInline(generic.GenericTabularInline):
    model = Media
    extra = 1
    
class EpisodeAdmin(admin.ModelAdmin):
    inlines = [
        MediaInline,
    ]

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])
+60 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ from django.conf import settings
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']
@@ -77,3 +77,62 @@ class GenericAdminViewTest(TestCase):
        # 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[-1]['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[-1]['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[-1]['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[-1]['inline_admin_formsets'][0].formset
        self.failIf('url' in formset.forms[0], 'The formset has excluded "url" field.')
 No newline at end of file