summaryrefslogtreecommitdiff
path: root/django/contrib/admin/options.py
diff options
context:
space:
mode:
Diffstat (limited to 'django/contrib/admin/options.py')
-rw-r--r--django/contrib/admin/options.py20
1 files changed, 18 insertions, 2 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 2d37f26de1..bb091e4c52 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -2022,10 +2022,27 @@ class ModelAdmin(BaseModelAdmin):
return queryset
return queryset.filter(pk__in=object_pks)
+ def _get_formset_with_permissions(self, request, queryset):
+ """
+ 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)
+
+ for form in formset.forms:
+ if not self.has_change_permission(request, form.instance):
+ for field_name in self.list_editable:
+ form.fields.pop(field_name, None)
+
+ return formset
+
def _save_formset(self, request, formset):
changecount = 0
with transaction.atomic(using=router.db_for_write(self.model)):
for form in formset.forms:
+ if not self.has_change_permission(request, form.instance):
+ continue
if form.has_changed():
obj = self.save_form(request, form, change=True)
if obj._state.adding:
@@ -2145,8 +2162,7 @@ class ModelAdmin(BaseModelAdmin):
# Handle GET -- construct a formset for display.
elif cl.list_editable and self.has_change_permission(request):
- FormSet = self.get_changelist_formset(request)
- cl.formset = FormSet(queryset=cl.result_list)
+ cl.formset = self._get_formset_with_permissions(request, cl.result_list)
# Build the list of media to be used by the formset.
if cl.formset: