#11383: Admin action 'Delete selected' check only global model delete permission
-------------------------------------+-------------------------------------
     Reporter:  krejcik@…            |                    Owner:  (none)
         Type:  Bug                  |                   Status:  new
    Component:  contrib.admin        |                  Version:  master
     Severity:  Normal               |               Resolution:
     Keywords:  delete permission    |             Triage Stage:  Accepted
  admin                              |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by rwlogel):

 There is a way to enforce bulk action deletes based on per object
 permissions.  We used the following approach:

 {{{#!python
 def has_delete_permission(self, request, obj=None):
     # Only superusers can delete
     if not request.user.is_superuser:
         return False

     if obj:
         # Code to check if obj is allowed to be deleted
         can_delete = .....
         return can_delete

     # Check if multiple items are selected to be deleted
     if (
         request.path.startswith('/admin/<path_to_model_being_deleted>')
 and
         request.POST and request.POST.get('action') == 'delete_selected'
     ):
         # Get list of ids that are going to be deleted
         id_list = request.POST.getlist(admin.helpers.ACTION_CHECKBOX_NAME)

         # Use id_list to lookup object or perform some query to see if
 that object can be deleted
         for id in id_list:
             can_delete = ....
             if not can_delete:
                 # This object can't be deleted so return False to prevent
 entire request
                 return False

     # User has delete permissions
     return True

 # If you want a custom error message
 def delete_selected(self, request, queryset):
     if not self.has_delete_permission(request):
         # You can also use
 request.POST.getlist(admin.helpers.ACTION_CHECKBOX_NAME)
         # to generate a even more detailed message.
         messages.error(request, 'One of the items selected can't be
 deleted')
         return

     return actions.delete_selected(self, request, queryset)

 delete_selected.short_description =
 actions.delete_selected.short_description

 actions = [delete_selected]
 }}}

 Unfortunately this approach no longer generates an appropriate error
 message as of 2.1 because the `has_delete_permission` method is also used
 to filter the actions.  So it will prevent the delete from happening but
 it just prints a warning `No action selected` because the action is
 filtered out before it can get to the actual delete permission check.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/11383#comment:17>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/071.1a96649b23b822b44bf1f8c416c54205%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to