diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/admin_views/admin.py | 12 | ||||
| -rw-r--r-- | tests/admin_views/tests.py | 49 |
2 files changed, 61 insertions, 0 deletions
diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py index 10fccca1a1..5e7a055ec3 100644 --- a/tests/admin_views/admin.py +++ b/tests/admin_views/admin.py @@ -377,6 +377,17 @@ class ParentWithUUIDPKNoAddAdmin(admin.ModelAdmin): return False +class PersonNoChangePermissionsAdmin9(admin.ModelAdmin): + list_display = ("name", "gender", "alive") + list_editable = ("gender", "alive") + ordering = ("id",) + + def has_change_permission(self, request, obj=None): + if obj is None: + return True + return obj.id % 2 == 0 + + class FooAccountAdmin(admin.StackedInline): model = FooAccount extra = 1 @@ -1491,6 +1502,7 @@ class ActorAdmin9(admin.ModelAdmin): site9 = admin.AdminSite(name="admin9") site9.register(Article, ArticleAdmin9) site9.register(Actor, ActorAdmin9) +site9.register(Person, PersonNoChangePermissionsAdmin9) site10 = admin.AdminSite(name="admin10") site10.final_catch_all_view = False diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 532f1e1ea0..bebd51b0df 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -5045,6 +5045,55 @@ class AdminViewListEditable(TestCase): 1, ) + def test_list_editable_per_object_permissions(self): + """ + List_editable fields are stripped for objects where the user + lacks change permissions, and retained for objects where the user has + permissions. + """ + self.client.logout() + self.client.force_login(self.superuser) + + response = self.client.get(reverse("admin9:admin_views_person_changelist")) + # Editable fields present + self.assertContains(response, 'name="form-1-gender"') + self.assertContains(response, 'name="form-1-alive"') + # Non-editable fields should NOT have inputs + self.assertNotContains(response, 'name="form-0-gender"') + self.assertNotContains(response, 'name="form-0-alive"') + self.assertNotContains(response, 'name="form-2-gender"') + self.assertNotContains(response, 'name="form-2-alive"') + + def test_list_editable_per_object_permissions_submission(self): + """ + Form submission updates only objects where the user has + change permissions, ignoring changes to unauthorized objects. + """ + self.client.logout() + self.client.force_login(self.superuser) + + data = { + "form-TOTAL_FORMS": "3", + "form-INITIAL_FORMS": "3", + "form-MAX_NUM_FORMS": "0", + "form-0-gender": "2", # Change per1 (not allowed) + "form-0-id": str(self.per1.pk), + "form-1-gender": "2", # Change per2 (allowed) + "form-1-id": str(self.per2.pk), + "form-2-gender": "2", # Change per3 (not allowed) + "form-2-id": str(self.per3.pk), + "_save": "Save", + } + response = self.client.post( + reverse("admin9:admin_views_person_changelist"), data, follow=True + ) + # per2 and per3 were updated, but per1 was not + self.assertEqual(Person.objects.get(pk=self.per1.pk).gender, 1) # Unchanged + self.assertEqual(Person.objects.get(pk=self.per2.pk).gender, 2) + self.assertEqual(Person.objects.get(pk=self.per3.pk).gender, 1) # Unchanged + # Check for success message + self.assertEqual(len(response.context["messages"]), 1) + @override_settings(ROOT_URLCONF="admin_views.urls") class AdminSearchTest(TestCase): |
