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.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@15722 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
c0fb9bd00b
commit
b921f1bac0
|
@ -1,5 +1,5 @@
|
||||||
{% if result_hidden_fields %}
|
{% if result_hidden_fields %}
|
||||||
<div class="hiddenfields"> {# DIV for HTML validation #}
|
<div class="hiddenfields">{# DIV for HTML validation #}
|
||||||
{% for item in result_hidden_fields %}{{ item }}{% endfor %}
|
{% for item in result_hidden_fields %}{{ item }}{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -188,7 +188,9 @@ def items_for_result(cl, result, form):
|
||||||
# By default the fields come from ModelAdmin.list_editable, but if we pull
|
# 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
|
# the fields out of the form instead of list_editable custom admins
|
||||||
# can provide fields on a per request basis
|
# 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]
|
bf = form[field_name]
|
||||||
result_repr = mark_safe(force_unicode(bf.errors) + force_unicode(bf))
|
result_repr = mark_safe(force_unicode(bf.errors) + force_unicode(bf))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -735,6 +735,28 @@ class CoverLetterAdmin(admin.ModelAdmin):
|
||||||
#return super(CoverLetterAdmin, self).queryset(request).only('author')
|
#return super(CoverLetterAdmin, self).queryset(request).only('author')
|
||||||
return super(CoverLetterAdmin, self).queryset(request).defer('date')
|
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(Article, ArticleAdmin)
|
||||||
admin.site.register(CustomArticle, CustomArticleAdmin)
|
admin.site.register(CustomArticle, CustomArticleAdmin)
|
||||||
|
@ -776,6 +798,8 @@ admin.site.register(FoodDelivery, FoodDeliveryAdmin)
|
||||||
admin.site.register(RowLevelChangePermissionModel, RowLevelChangePermissionModelAdmin)
|
admin.site.register(RowLevelChangePermissionModel, RowLevelChangePermissionModelAdmin)
|
||||||
admin.site.register(Paper, PaperAdmin)
|
admin.site.register(Paper, PaperAdmin)
|
||||||
admin.site.register(CoverLetter, CoverLetterAdmin)
|
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.
|
# We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
|
||||||
# That way we cover all four cases:
|
# That way we cover all four cases:
|
||||||
|
|
|
@ -36,7 +36,7 @@ from models import (Article, BarAccount, CustomArticle, EmptyModel,
|
||||||
Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit,
|
Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit,
|
||||||
Category, Post, Plot, FunkyTag, Chapter, Book, Promo, WorkHour, Employee,
|
Category, Post, Plot, FunkyTag, Chapter, Book, Promo, WorkHour, Employee,
|
||||||
Question, Answer, Inquisition, Actor, FoodDelivery,
|
Question, Answer, Inquisition, Actor, FoodDelivery,
|
||||||
RowLevelChangePermissionModel, Paper, CoverLetter)
|
RowLevelChangePermissionModel, Paper, CoverLetter, Story, OtherStory)
|
||||||
|
|
||||||
|
|
||||||
class AdminViewBasicTest(TestCase):
|
class AdminViewBasicTest(TestCase):
|
||||||
|
@ -1678,6 +1678,36 @@ class AdminViewListEditable(TestCase):
|
||||||
response = self.client.get('/test_admin/admin/admin_views/person/?%s' % IS_POPUP_VAR)
|
response = self.client.get('/test_admin/admin/admin_views/person/?%s' % IS_POPUP_VAR)
|
||||||
self.assertEqual(response.context['cl'].list_editable, ())
|
self.assertEqual(response.context['cl'].list_editable, ())
|
||||||
|
|
||||||
|
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):
|
class AdminSearchTest(TestCase):
|
||||||
fixtures = ['admin-views-users', 'multiple-child-classes',
|
fixtures = ['admin-views-users', 'multiple-child-classes',
|
||||||
|
|
Loading…
Reference in New Issue