diff options
| -rw-r--r-- | django/contrib/admin/options.py | 13 | ||||
| -rw-r--r-- | tests/admin_views/admin.py | 2 | ||||
| -rw-r--r-- | tests/admin_views/tests.py | 36 |
3 files changed, 30 insertions, 21 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index e5502c42d5..e05881b16a 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -2026,13 +2026,16 @@ class ModelAdmin(BaseModelAdmin): return queryset return queryset.filter(pk__in=object_pks) - def _get_formset_with_permissions(self, request, queryset): + def _get_formset_with_permissions(self, request, queryset, for_save=False): """ Construct a changelist formset, and remove list_editable fields for objects the user cannot change. """ FormSet = self.get_changelist_formset(request) - formset = FormSet(queryset=queryset) + if for_save: + formset = FormSet(data=request.POST, files=request.FILES, queryset=queryset) + else: + formset = FormSet(queryset=queryset) for form in formset.forms: if not self.has_change_permission(request, form.instance): @@ -2158,7 +2161,11 @@ class ModelAdmin(BaseModelAdmin): modified_objects = self._get_list_editable_queryset( request, FormSet.get_default_prefix() ) - cl.formset = FormSet(request.POST, request.FILES, queryset=modified_objects) + cl.formset = self._get_formset_with_permissions( + request, + queryset=modified_objects, + for_save=True, + ) if cl.formset.is_valid(): self._save_formset(request, cl.formset) diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py index 5e7a055ec3..d0448a1b64 100644 --- a/tests/admin_views/admin.py +++ b/tests/admin_views/admin.py @@ -385,7 +385,7 @@ class PersonNoChangePermissionsAdmin9(admin.ModelAdmin): def has_change_permission(self, request, obj=None): if obj is None: return True - return obj.id % 2 == 0 + return obj.alive class FooAccountAdmin(admin.StackedInline): diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 1fdb90822c..3dba13d185 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -5076,14 +5076,14 @@ class AdminViewListEditable(TestCase): 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"') + # Non-editable fields should NOT have inputs. + self.assertNotContains(response, 'name="form-1-gender"') + self.assertNotContains(response, 'name="form-1-alive"') + # Editable fields are present. + self.assertContains(response, 'name="form-0-gender"') + self.assertContains(response, 'name="form-0-alive"') + self.assertContains(response, 'name="form-2-gender"') + self.assertContains(response, 'name="form-2-alive"') def test_list_editable_per_object_permissions_submission(self): """ @@ -5092,26 +5092,28 @@ class AdminViewListEditable(TestCase): """ self.client.logout() self.client.force_login(self.superuser) - + # Skip the instance lacking edit permission (include only its id). data = { "form-TOTAL_FORMS": "3", "form-INITIAL_FORMS": "3", "form-MAX_NUM_FORMS": "0", - "form-0-gender": "2", # Change per1 (not allowed) + "form-0-gender": "2", + "form-0-alive": "checked", "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-1-id": str(self.per2.pk), # not editable + "form-2-gender": "2", + "form-2-alive": "checked", "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 + # per1 and per3 were updated, but per2 was not. + self.assertEqual(Person.objects.get(pk=self.per1.pk).gender, 2) + self.assertEqual(Person.objects.get(pk=self.per2.pk).gender, 1) # Unchanged + self.assertEqual(Person.objects.get(pk=self.per3.pk).gender, 2) + # Check for success message self.assertEqual(len(response.context["messages"]), 1) |
