summaryrefslogtreecommitdiff
path: root/tests/admin_views
diff options
context:
space:
mode:
authorPaulo <commonzenpython@gmail.com>2017-08-22 19:48:55 -0400
committerTim Graham <timograham@gmail.com>2018-01-04 19:07:46 -0500
commitd1286a8a689e31435c07534fee7b61f41cea37f8 (patch)
tree1b74eafe481b46ee763c05957d51cef0d43671a6 /tests/admin_views
parent5d5a2bd299c97f8e03d79380345ec8713d612f58 (diff)
Fixed #28517 -- Fixed admin delete confirmation view crash when related models don't have a delete permission.
Diffstat (limited to 'tests/admin_views')
-rw-r--r--tests/admin_views/admin.py24
-rw-r--r--tests/admin_views/models.py8
-rw-r--r--tests/admin_views/tests.py23
3 files changed, 47 insertions, 8 deletions
diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py
index 1e4124fca5..12087865b4 100644
--- a/tests/admin_views/admin.py
+++ b/tests/admin_views/admin.py
@@ -36,11 +36,11 @@ from .models import (
Person, Persona, Picture, Pizza, Plot, PlotDetails, PlotProxy,
PluggableSearchPerson, Podcast, Post, PrePopulatedPost,
PrePopulatedPostLargeSlug, PrePopulatedSubPost, Promo, Question,
- ReadablePizza, Recipe, Recommendation, Recommender, ReferencedByGenRel,
- ReferencedByInline, ReferencedByParent, RelatedPrepopulated,
- RelatedWithUUIDPKModel, Report, Reservation, Restaurant,
- RowLevelChangePermissionModel, Section, ShortMessage, Simple, Sketch,
- State, Story, StumpJoke, Subscriber, SuperVillain, Telegram, Thing,
+ ReadablePizza, ReadOnlyPizza, Recipe, Recommendation, Recommender,
+ ReferencedByGenRel, ReferencedByInline, ReferencedByParent,
+ RelatedPrepopulated, RelatedWithUUIDPKModel, Report, Reservation,
+ Restaurant, RowLevelChangePermissionModel, Section, ShortMessage, Simple,
+ Sketch, State, Story, StumpJoke, Subscriber, SuperVillain, Telegram, Thing,
Topping, UnchangeableObject, UndeletableObject, UnorderedObject,
UserMessenger, Villain, Vodcast, Whatsit, Widget, Worker, WorkHour,
)
@@ -502,6 +502,19 @@ class StudentAdmin(admin.ModelAdmin):
search_fields = ('name',)
+class ReadOnlyPizzaAdmin(admin.ModelAdmin):
+ readonly_fields = ('name', 'toppings')
+
+ def has_add_permission(self, request):
+ return False
+
+ def has_change_permission(self, request, obj=None):
+ return True
+
+ def has_delete_permission(self, request, obj=None):
+ return True
+
+
class WorkHourAdmin(admin.ModelAdmin):
list_display = ('datum', 'employee')
list_filter = ('employee',)
@@ -1001,6 +1014,7 @@ site.register(Book, inlines=[ChapterInline])
site.register(Promo)
site.register(ChapterXtra1, ChapterXtra1Admin)
site.register(Pizza, PizzaAdmin)
+site.register(ReadOnlyPizza, ReadOnlyPizzaAdmin)
site.register(ReadablePizza)
site.register(Topping, ToppingAdmin)
site.register(Album, AlbumAdmin)
diff --git a/tests/admin_views/models.py b/tests/admin_views/models.py
index fc229cf3bd..38565b0a7f 100644
--- a/tests/admin_views/models.py
+++ b/tests/admin_views/models.py
@@ -582,6 +582,14 @@ class ReadablePizza(Pizza):
proxy = True
+# No default permissions are created for this model and both name and toppings
+# are readonly for this model's admin.
+class ReadOnlyPizza(Pizza):
+ class Meta:
+ proxy = True
+ default_permissions = ()
+
+
class Album(models.Model):
owner = models.ForeignKey(User, models.SET_NULL, null=True, blank=True)
title = models.CharField(max_length=30)
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index 5bcc1942a5..b8093c2971 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -48,9 +48,9 @@ from .models import (
MainPrepopulated, Media, ModelWithStringPrimaryKey, OtherStory, Paper,
Parent, ParentWithDependentChildren, ParentWithUUIDPK, Person, Persona,
Picture, Pizza, Plot, PlotDetails, PluggableSearchPerson, Podcast, Post,
- PrePopulatedPost, Promo, Question, ReadablePizza, Recommendation,
- Recommender, RelatedPrepopulated, RelatedWithUUIDPKModel, Report,
- Restaurant, RowLevelChangePermissionModel, SecretHideout, Section,
+ PrePopulatedPost, Promo, Question, ReadablePizza, ReadOnlyPizza,
+ Recommendation, Recommender, RelatedPrepopulated, RelatedWithUUIDPKModel,
+ Report, Restaurant, RowLevelChangePermissionModel, SecretHideout, Section,
ShortMessage, Simple, State, Story, SuperSecretHideout, SuperVillain,
Telegram, TitleTranslation, Topping, UnchangeableObject, UndeletableObject,
UnorderedObject, Villain, Vodcast, Whatsit, Widget, Worker, WorkHour,
@@ -1820,6 +1820,23 @@ class AdminViewPermissionsTest(TestCase):
logged = LogEntry.objects.get(content_type=article_ct, action_flag=DELETION)
self.assertEqual(logged.object_id, str(self.a1.pk))
+ def test_delete_view_with_no_default_permissions(self):
+ """
+ The delete view allows users to delete collected objects without a
+ 'delete' permission (ReadOnlyPizza.Meta.default_permissions is empty).
+ """
+ pizza = ReadOnlyPizza.objects.create(name='Double Cheese')
+ delete_url = reverse('admin:admin_views_readonlypizza_delete', args=(pizza.pk,))
+ self.client.force_login(self.adduser)
+ response = self.client.get(delete_url)
+ self.assertContains(response, 'admin_views/readonlypizza/%s/' % pizza.pk)
+ self.assertContains(response, '<h2>Summary</h2>')
+ self.assertContains(response, '<li>Read only pizzas: 1</li>')
+ self.assertEqual(response.status_code, 200)
+ post = self.client.post(delete_url, {'post': 'yes'})
+ self.assertRedirects(post, reverse('admin:admin_views_readonlypizza_changelist'))
+ self.assertEqual(ReadOnlyPizza.objects.count(), 0)
+
def test_delete_view_nonexistent_obj(self):
self.client.force_login(self.deleteuser)
url = reverse('admin:admin_views_article_delete', args=('nonexistent',))