diff options
| author | Basil Dubyk <samitnuk.work@gmail.com> | 2018-11-09 22:41:55 +0200 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2018-11-28 15:50:30 -0500 |
| commit | 381bdd4898bffbe1cbd3020826e6bf4c7cc63254 (patch) | |
| tree | 7f14f9e137ee27efe85e2c1f7c67c786e5dc1bad | |
| parent | a9d9680ea344a243f6e3ed7d0ad8031172458b9a (diff) | |
[2.1.x] Fixed #29929 -- Fixed admin view-only change form crash when using ModelAdmin.prepopulated_fields.
Backport of 7d1123e5ada60963ba3c708a8932e57342278706 from master.
| -rw-r--r-- | django/contrib/admin/options.py | 3 | ||||
| -rw-r--r-- | docs/releases/2.1.4.txt | 3 | ||||
| -rw-r--r-- | tests/admin_views/admin.py | 8 | ||||
| -rw-r--r-- | tests/admin_views/tests.py | 19 |
4 files changed, 32 insertions, 1 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 4175eca614..d0948359ab 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -1588,7 +1588,8 @@ class ModelAdmin(BaseModelAdmin): 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 diff --git a/docs/releases/2.1.4.txt b/docs/releases/2.1.4.txt index 081b56991d..8ba457846e 100644 --- a/docs/releases/2.1.4.txt +++ b/docs/releases/2.1.4.txt @@ -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`). diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py index 04cc6c79e7..5dc2a5811b 100644 --- a/tests/admin_views/admin.py +++ b/tests/admin_views/admin.py @@ -459,6 +459,13 @@ class PrePopulatedPostAdmin(admin.ModelAdmin): 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 = ( @@ -1085,6 +1092,7 @@ site2.register(Person, save_as_continue=False) 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(). diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 3930eca929..2d1e58aa26 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -4218,6 +4218,25 @@ class PrePopulatedTest(TestCase): 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): |
