From 01c392623d988d7486bdaa870886df0ea3da5fa7 Mon Sep 17 00:00:00 2001 From: Julien Phalip Date: Sat, 21 Jul 2012 18:10:24 -0700 Subject: [PATCH] Fixed #10057 -- Ensured that the 'show_delete' context variable in the admin's change view actually controls the display of the delete button. Thanks to rajeesh for the report, to patcoll for the patch, and to David Gouldin for the test. --- django/contrib/admin/options.py | 1 - django/contrib/admin/templatetags/admin_modify.py | 2 +- tests/regressiontests/admin_views/admin.py | 8 +++++++- tests/regressiontests/admin_views/customadmin.py | 1 + tests/regressiontests/admin_views/models.py | 7 +++++++ tests/regressiontests/admin_views/tests.py | 13 ++++++++++++- 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 4d23f8f384..40f6e2842c 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -998,7 +998,6 @@ class ModelAdmin(BaseModelAdmin): 'title': _('Add %s') % force_unicode(opts.verbose_name), 'adminform': adminForm, 'is_popup': "_popup" in request.REQUEST, - 'show_delete': False, 'media': media, 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), diff --git a/django/contrib/admin/templatetags/admin_modify.py b/django/contrib/admin/templatetags/admin_modify.py index e55b3bf2bd..c190533f95 100644 --- a/django/contrib/admin/templatetags/admin_modify.py +++ b/django/contrib/admin/templatetags/admin_modify.py @@ -32,7 +32,7 @@ def submit_row(context): 'onclick_attrib': (opts.get_ordered_objects() and change and 'onclick="submitOrderForm();"' or ''), 'show_delete_link': (not is_popup and context['has_delete_permission'] - and (change or context['show_delete'])), + and change and context.get('show_delete', True)), 'show_save_as_new': not is_popup and change and save_as, 'show_save_and_add_another': context['has_add_permission'] and not is_popup and (not save_as or context['add']), diff --git a/tests/regressiontests/admin_views/admin.py b/tests/regressiontests/admin_views/admin.py index 01a19e6373..6ec933f89b 100644 --- a/tests/regressiontests/admin_views/admin.py +++ b/tests/regressiontests/admin_views/admin.py @@ -27,7 +27,7 @@ from .models import (Article, Chapter, Account, Media, Child, Parent, Picture, Album, Question, Answer, ComplexSortedPerson, PrePopulatedPostLargeSlug, AdminOrderedField, AdminOrderedModelMethod, AdminOrderedAdminMethod, AdminOrderedCallable, Report, Color2, UnorderedObject, MainPrepopulated, - RelatedPrepopulated) + RelatedPrepopulated, UndeletableObject) def callable_year(dt_value): @@ -569,6 +569,11 @@ class UnorderedObjectAdmin(admin.ModelAdmin): list_per_page = 2 +class UndeletableObjectAdmin(admin.ModelAdmin): + def change_view(self, *args, **kwargs): + kwargs['extra_context'] = {'show_delete': False} + return super(UndeletableObjectAdmin, self).change_view(*args, **kwargs) + site = admin.AdminSite(name="admin") site.register(Article, ArticleAdmin) @@ -616,6 +621,7 @@ site.register(OtherStory, OtherStoryAdmin) site.register(Report, ReportAdmin) site.register(MainPrepopulated, MainPrepopulatedAdmin) site.register(UnorderedObject, UnorderedObjectAdmin) +site.register(UndeletableObject, UndeletableObjectAdmin) # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2. # That way we cover all four cases: diff --git a/tests/regressiontests/admin_views/customadmin.py b/tests/regressiontests/admin_views/customadmin.py index d205e0e290..142527b022 100644 --- a/tests/regressiontests/admin_views/customadmin.py +++ b/tests/regressiontests/admin_views/customadmin.py @@ -48,3 +48,4 @@ site.register(models.Thing, base_admin.ThingAdmin) site.register(models.Fabric, base_admin.FabricAdmin) site.register(models.ChapterXtra1, base_admin.ChapterXtra1Admin) site.register(User, UserLimitedAdmin) +site.register(models.UndeletableObject, base_admin.UndeletableObjectAdmin) diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py index ab2bc202f9..aee193b572 100644 --- a/tests/regressiontests/admin_views/models.py +++ b/tests/regressiontests/admin_views/models.py @@ -611,3 +611,10 @@ class UnorderedObject(models.Model): """ name = models.CharField(max_length=255) bool = models.BooleanField(default=True) + +class UndeletableObject(models.Model): + """ + Model whose show_delete in admin change_view has been disabled + Refs #10057. + """ + name = models.CharField(max_length=255) diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index 49ec3c1945..630758a91d 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -41,7 +41,8 @@ from .models import (Article, BarAccount, CustomArticle, EmptyModel, FooAccount, FoodDelivery, RowLevelChangePermissionModel, Paper, CoverLetter, Story, OtherStory, ComplexSortedPerson, Parent, Child, AdminOrderedField, AdminOrderedModelMethod, AdminOrderedAdminMethod, AdminOrderedCallable, - Report, MainPrepopulated, RelatedPrepopulated, UnorderedObject) + Report, MainPrepopulated, RelatedPrepopulated, UnorderedObject, + UndeletableObject) ERROR_MESSAGE = "Please enter the correct username and password \ @@ -588,6 +589,16 @@ class AdminViewBasicTest(TestCase): self.assertFalse(reverse('admin:password_change') in response.content, msg='The "change password" link should not be displayed if a user does not have a usable password.') + def test_change_view_with_show_delete_extra_context(self): + """ + Ensured that the 'show_delete' context variable in the admin's change + view actually controls the display of the delete button. + Refs #10057. + """ + instance = UndeletableObject.objects.create(name='foo') + response = self.client.get('/test_admin/%s/admin_views/undeletableobject/%d/' % + (self.urlbit, instance.pk)) + self.assertNotContains(response, 'deletelink') @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',)) class AdminViewFormUrlTest(TestCase):