Fixed #29419 -- Allowed permissioning of admin actions.

This commit is contained in:
Carlton Gibson 2018-06-18 21:07:29 +02:00 committed by Tim Graham
parent 6dd4edb1b4
commit 958c7b301e
9 changed files with 192 additions and 17 deletions

View file

@ -579,6 +579,8 @@ with the admin site:
which does not refer to a Field.
* **admin.E128**: The value of ``date_hierarchy`` must be a ``DateField`` or
``DateTimeField``.
* **admin.E129**: ``<modeladmin>`` must define a ``has_<foo>_permission()``
method for the ``<action>`` action.
``InlineModelAdmin``
~~~~~~~~~~~~~~~~~~~~

View file

@ -357,3 +357,52 @@ Conditionally enabling or disabling actions
if 'delete_selected' in actions:
del actions['delete_selected']
return actions
.. _admin-action-permissions:
Setting permissions for actions
-------------------------------
.. versionadded:: 2.1
Actions may limit their availability to users with specific permissions by
setting an ``allowed_permissions`` attribute on the action function::
def make_published(modeladmin, request, queryset):
queryset.update(status='p')
make_published.allowed_permissions = ('change',)
The ``make_published()`` action will only be available to users that pass the
:meth:`.ModelAdmin.has_change_permission` check.
If ``allowed_permissions`` has more than one permission, the action will be
available as long as the user passes at least one of the checks.
Available values for ``allowed_permissions`` and the corresponding method
checks are:
- ``'add'``: :meth:`.ModelAdmin.has_add_permission`
- ``'change'``: :meth:`.ModelAdmin.has_change_permission`
- ``'delete'``: :meth:`.ModelAdmin.has_delete_permission`
- ``'view'``: :meth:`.ModelAdmin.has_view_permission`
You can specify any other value as long as you implement a corresponding
``has_<value>_permission(self, request)`` method on the ``ModelAdmin``.
For example::
from django.contrib import admin
from django.contrib.auth import get_permission_codename
class ArticleAdmin(admin.ModelAdmin):
actions = ['make_published']
def make_published(self, request, queryset):
queryset.update(status='p')
make_published.allowed_permissions = ('publish',)
def has_publish_permission(self, request):
"""Does the user have the publish permission?"""
opts = self.opts
codename = get_permission_codename('publish', opts)
return request.user.has_perm('%s.%s' % (opts.app_label, codename))

View file

@ -82,6 +82,9 @@ Minor features
* :meth:`.InlineModelAdmin.has_add_permission` is now passed the parent object
as the second positional argument, ``obj``.
* Admin actions may now :ref:`specify permissions <admin-action-permissions>`
to limit their availability to certain users.
:mod:`django.contrib.auth`
~~~~~~~~~~~~~~~~~~~~~~~~~~