Skip to content

Commit

Permalink
Fixed #29929 -- Fixed admin view-only change form crash when using Mo…
Browse files Browse the repository at this point in the history
…delAdmin.prepopulated_fields.
  • Loading branch information
samitnuk authored and timgraham committed Nov 28, 2018
1 parent 682cdf6 commit 7d1123e
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 1 deletion.
3 changes: 2 additions & 1 deletion django/contrib/admin/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -1585,7 +1585,8 @@ def _changeform_view(self, request, object_id, form_url, extra_context):
adminForm = helpers.AdminForm(
form,
list(self.get_fieldsets(request, obj)),
self.get_prepopulated_fields(request, obj),
# Clear prepopulated fields on a view-only form to avoid a crash.
self.get_prepopulated_fields(request, obj) if add or self.has_change_permission(request, obj) else {},
readonly_fields,
model_admin=self)
media = self.media + adminForm.media
Expand Down
3 changes: 3 additions & 0 deletions docs/releases/2.1.4.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ Bugfixes

* Fixed keep-alive support in ``runserver`` after it was disabled to fix
another issue in Django 2.0 (:ticket:`29849`).

* Fixed admin view-only change form crash when using
``ModelAdmin.prepopulated_fields`` (:ticket:`29929`).
8 changes: 8 additions & 0 deletions tests/admin_views/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,13 @@ def get_prepopulated_fields(self, request, obj=None):
return self.prepopulated_fields


class PrePopulatedPostReadOnlyAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('title',)}

def has_change_permission(self, *args, **kwargs):
return False


class PostAdmin(admin.ModelAdmin):
list_display = ['title', 'public']
readonly_fields = (
Expand Down Expand Up @@ -1085,6 +1092,7 @@ def get_formsets_with_inlines(self, request, obj=None):
site7 = admin.AdminSite(name="admin7")
site7.register(Article, ArticleAdmin2)
site7.register(Section)
site7.register(PrePopulatedPost, PrePopulatedPostReadOnlyAdmin)


# Used to test ModelAdmin.sortable_by and get_sortable_by().
Expand Down
19 changes: 19 additions & 0 deletions tests/admin_views/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4211,6 +4211,25 @@ def test_prepopulated_maxlength_localized(self):
response = self.client.get(reverse('admin:admin_views_prepopulatedpostlargeslug_add'))
self.assertContains(response, ""maxLength": 1000") # instead of 1,000

def test_view_only_add_form(self):
"""
PrePopulatedPostReadOnlyAdmin.prepopulated_fields includes 'slug'
which is present in the add view, even if the
ModelAdmin.has_change_permission() returns False.
"""
response = self.client.get(reverse('admin7:admin_views_prepopulatedpost_add'))
self.assertContains(response, 'data-prepopulated-fields=')
self.assertContains(response, '"id": "#id_slug"')

def test_view_only_change_form(self):
"""
PrePopulatedPostReadOnlyAdmin.prepopulated_fields includes 'slug'. That
doesn't break a view-only change view.
"""
response = self.client.get(reverse('admin7:admin_views_prepopulatedpost_change', args=(self.p1.pk,)))
self.assertContains(response, 'data-prepopulated-fields="[]"')
self.assertContains(response, '<div class="readonly">%s</div>' % self.p1.slug)


@override_settings(ROOT_URLCONF='admin_views.urls')
class SeleniumTests(AdminSeleniumTestCase):
Expand Down

0 comments on commit 7d1123e

Please sign in to comment.