Commit 0516b998 authored by Jannis Leidel's avatar Jannis Leidel
Browse files

[1.2.X] Fixed #12475 -- Fixed an edge case with hidden fields in ModelAdmin...

[1.2.X] Fixed #12475 -- Fixed an edge case with hidden fields in ModelAdmin changelists when used in conjunction with list_display_links or list_editable. Thanks, Simon Meers, Julien Phalip, Karen and master.

Backport from trunk (r15722).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15724 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 1985ca77
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -189,7 +189,9 @@ def items_for_result(cl, result, form):
            # By default the fields come from ModelAdmin.list_editable, but if we pull
            # the fields out of the form instead of list_editable custom admins
            # can provide fields on a per request basis
            if form and field_name in form.fields:
            if (form and field_name in form.fields and not (
                    field_name == cl.model._meta.pk.name and
                        form[cl.model._meta.pk.name].is_hidden)):
                bf = form[field_name]
                result_repr = mark_safe(force_unicode(bf.errors) + force_unicode(bf))
            else:
+24 −0
Original line number Diff line number Diff line
@@ -698,6 +698,28 @@ class CoverLetterAdmin(admin.ModelAdmin):
        #return super(CoverLetterAdmin, self).queryset(request).only('author')
        return super(CoverLetterAdmin, self).queryset(request).defer('date')

class Story(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()

class StoryForm(forms.ModelForm):
    class Meta:
        widgets = {'title': forms.HiddenInput}

class StoryAdmin(admin.ModelAdmin):
    list_display = ('id', 'title', 'content')
    list_display_links = ('title',) # 'id' not in list_display_links
    list_editable = ('content', )
    form = StoryForm

class OtherStory(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()

class OtherStoryAdmin(admin.ModelAdmin):
    list_display = ('id', 'title', 'content')
    list_display_links = ('title', 'id') # 'id' in list_display_links
    list_editable = ('content', )

admin.site.register(Article, ArticleAdmin)
admin.site.register(CustomArticle, CustomArticleAdmin)
@@ -739,6 +761,8 @@ admin.site.register(FoodDelivery, FoodDeliveryAdmin)
admin.site.register(RowLevelChangePermissionModel, RowLevelChangePermissionModelAdmin)
admin.site.register(Paper, PaperAdmin)
admin.site.register(CoverLetter, CoverLetterAdmin)
admin.site.register(Story, StoryAdmin)
admin.site.register(OtherStory, OtherStoryAdmin)

# We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
# That way we cover all four cases:
+32 −1
Original line number Diff line number Diff line
@@ -31,7 +31,8 @@ from models import (Article, BarAccount, CustomArticle, EmptyModel,
    Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast,
    Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit,
    Category, Post, Plot, FunkyTag, WorkHour, Employee, Inquisition,
    Actor, FoodDelivery, RowLevelChangePermissionModel, Paper, CoverLetter)
    Actor, FoodDelivery, RowLevelChangePermissionModel, Paper, CoverLetter,
    Story, OtherStory)


class AdminViewBasicTest(TestCase):
@@ -1540,6 +1541,36 @@ class AdminViewListEditable(TestCase):



    def test_pk_hidden_fields(self):
        """ Ensure that hidden pk fields aren't displayed in the table body and
            that their corresponding human-readable value is displayed instead.
            Note that the hidden pk fields are in fact be displayed but
            separately (not in the table), and only once.
            Refs #12475.
        """
        Story.objects.create(title='The adventures of Guido', content='Once upon a time in Djangoland...')
        Story.objects.create(title='Crouching Tiger, Hidden Python', content='The Python was sneaking into...')
        response = self.client.get('/test_admin/admin/admin_views/story/')
        self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table.
        self.assertContains(response, 'id="id_form-1-id"', 1)
        self.assertContains(response, '<div class="hiddenfields">\n<input type="hidden" name="form-0-id" value="2" id="id_form-0-id" /><input type="hidden" name="form-1-id" value="1" id="id_form-1-id" />\n</div>')
        self.assertContains(response, '<td>1</td>', 1)
        self.assertContains(response, '<td>2</td>', 1)

    def test_pk_hidden_fields_with_list_display_links(self):
        """ Similarly as test_pk_hidden_fields, but when the hidden pk fields are
            referenced in list_display_links.
            Refs #12475.
        """
        OtherStory.objects.create(title='The adventures of Guido', content='Once upon a time in Djangoland...')
        OtherStory.objects.create(title='Crouching Tiger, Hidden Python', content='The Python was sneaking into...')
        response = self.client.get('/test_admin/admin/admin_views/otherstory/')
        self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table.
        self.assertContains(response, 'id="id_form-1-id"', 1)
        self.assertContains(response, '<div class="hiddenfields">\n<input type="hidden" name="form-0-id" value="2" id="id_form-0-id" /><input type="hidden" name="form-1-id" value="1" id="id_form-1-id" />\n</div>')
        self.assertContains(response, '<th><a href="1/">1</a></th>', 1)
        self.assertContains(response, '<th><a href="2/">2</a></th>', 1)


class AdminSearchTest(TestCase):
    fixtures = ['admin-views-users','multiple-child-classes']
+1 −1

File changed.

Contains only whitespace changes.