diff --git a/django/django/contrib/admin/actions.py b/django/django/contrib/admin/actions.py
index 29fe28c..2c4b7b7 100644
a
|
b
|
def delete_selected(modeladmin, request, queryset):
|
30 | 30 | opts = modeladmin.model._meta |
31 | 31 | app_label = opts.app_label |
32 | 32 | |
33 | | # Check that the user has delete permission for the actual model |
34 | | if not modeladmin.has_delete_permission(request): |
35 | | raise PermissionDenied |
36 | | |
37 | 33 | # Populate deletable_objects, a data structure of all related objects that |
38 | 34 | # will also be deleted. |
39 | 35 | |
… |
… |
def delete_selected(modeladmin, request, queryset):
|
87 | 83 | ], context, context_instance=template.RequestContext(request)) |
88 | 84 | |
89 | 85 | delete_selected.short_description = ugettext_lazy("Delete selected %(verbose_name_plural)s") |
| 86 | delete_selected.has_permission = lambda admin, request: admin.has_delete_permission(request) |
diff --git a/django/django/contrib/admin/options.py b/django/django/contrib/admin/options.py
index 4638f7e..ad5c2f1 100644
a
|
b
|
class ModelAdmin(BaseModelAdmin):
|
455 | 455 | continue |
456 | 456 | actions.extend([self.get_action(action) for action in class_actions]) |
457 | 457 | |
458 | | # get_action might have returned None, so filter any of those out. |
459 | | actions = filter(None, actions) |
| 458 | # get_action might have returned None, so filter any of those out and |
| 459 | # ensure that the action is usable in the current context. |
| 460 | actions = [a for a in actions if a and (not hasattr(a[0], 'has_permission') or a[0].has_permission(self, request))] |
460 | 461 | |
461 | 462 | # Convert the actions into a SortedDict keyed by name |
462 | 463 | # and sorted by description. |