Loading django/contrib/admin/options.py +13 −0 Original line number Diff line number Diff line Loading @@ -473,6 +473,19 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): codename = get_permission_codename('delete', opts) return request.user.has_perm("%s.%s" % (opts.app_label, codename)) def has_module_permission(self, request): """ Returns True if the given request has any permission in the given app label. Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to view the module on the admin index page and access the module's index page. Overriding it does not restrict access to the add, change or delete views. Use `ModelAdmin.has_(add|change|delete)_permission` for that. """ return request.user.has_module_perms(self.opts.app_label) @python_2_unicode_compatible class ModelAdmin(BaseModelAdmin): Loading django/contrib/admin/sites.py +5 −6 Original line number Diff line number Diff line Loading @@ -367,10 +367,9 @@ class AdminSite(object): apps that have been registered in this site. """ app_dict = {} user = request.user for model, model_admin in self._registry.items(): app_label = model._meta.app_label has_module_perms = user.has_module_perms(app_label) has_module_perms = model_admin.has_module_permission(request) if has_module_perms: perms = model_admin.get_model_perms(request) Loading Loading @@ -424,14 +423,14 @@ class AdminSite(object): current_app=self.name) def app_index(self, request, app_label, extra_context=None): user = request.user app_name = apps.get_app_config(app_label).verbose_name has_module_perms = user.has_module_perms(app_label) if not has_module_perms: raise PermissionDenied app_dict = {} for model, model_admin in self._registry.items(): if app_label == model._meta.app_label: has_module_perms = model_admin.has_module_permission(request) if not has_module_perms: raise PermissionDenied perms = model_admin.get_model_perms(request) # Check whether user has any perm for this module. Loading docs/ref/contrib/admin/index.txt +14 −0 Original line number Diff line number Diff line Loading @@ -1631,6 +1631,19 @@ templates used by the :class:`ModelAdmin` views: be interpreted as meaning that the current user is not permitted to delete any object of this type). .. method:: ModelAdmin.has_module_permission(request) .. versionadded:: 1.8 Should return ``True`` if displaying the module on the admin index page and accessing the module's index page is permitted, ``False`` otherwise. Uses :meth:`User.has_module_perms() <django.contrib.auth.models.User.has_module_perms>` by default. Overriding it does not restrict access to the add, change or delete views, :meth:`~ModelAdmin.has_add_permission`, :meth:`~ModelAdmin.has_change_permission`, and :meth:`~ModelAdmin.has_delete_permission` should be used for that. .. method:: ModelAdmin.get_queryset(request) The ``get_queryset`` method on a ``ModelAdmin`` returns a Loading Loading @@ -1909,6 +1922,7 @@ adds some of its own (the shared features are actually defined in the - :meth:`~ModelAdmin.has_add_permission` - :meth:`~ModelAdmin.has_change_permission` - :meth:`~ModelAdmin.has_delete_permission` - :meth:`~ModelAdmin.has_module_permission` The ``InlineModelAdmin`` class adds: Loading docs/releases/1.8.txt +3 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,9 @@ Minor features :mod:`django.contrib.admin` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ * ... * :class:`~django.contrib.admin.ModelAdmin` now has a :meth:`~django.contrib.admin.ModelAdmin.has_module_permission` method to allow limiting access to the module on the admin index page. :mod:`django.contrib.auth` ^^^^^^^^^^^^^^^^^^^^^^^^^^ Loading tests/admin_ordering/tests.py +3 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,9 @@ class MockSuperUser(object): def has_perm(self, perm): return True def has_module_perms(self, module): return True request = MockRequest() request.user = MockSuperUser() Loading Loading
django/contrib/admin/options.py +13 −0 Original line number Diff line number Diff line Loading @@ -473,6 +473,19 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): codename = get_permission_codename('delete', opts) return request.user.has_perm("%s.%s" % (opts.app_label, codename)) def has_module_permission(self, request): """ Returns True if the given request has any permission in the given app label. Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to view the module on the admin index page and access the module's index page. Overriding it does not restrict access to the add, change or delete views. Use `ModelAdmin.has_(add|change|delete)_permission` for that. """ return request.user.has_module_perms(self.opts.app_label) @python_2_unicode_compatible class ModelAdmin(BaseModelAdmin): Loading
django/contrib/admin/sites.py +5 −6 Original line number Diff line number Diff line Loading @@ -367,10 +367,9 @@ class AdminSite(object): apps that have been registered in this site. """ app_dict = {} user = request.user for model, model_admin in self._registry.items(): app_label = model._meta.app_label has_module_perms = user.has_module_perms(app_label) has_module_perms = model_admin.has_module_permission(request) if has_module_perms: perms = model_admin.get_model_perms(request) Loading Loading @@ -424,14 +423,14 @@ class AdminSite(object): current_app=self.name) def app_index(self, request, app_label, extra_context=None): user = request.user app_name = apps.get_app_config(app_label).verbose_name has_module_perms = user.has_module_perms(app_label) if not has_module_perms: raise PermissionDenied app_dict = {} for model, model_admin in self._registry.items(): if app_label == model._meta.app_label: has_module_perms = model_admin.has_module_permission(request) if not has_module_perms: raise PermissionDenied perms = model_admin.get_model_perms(request) # Check whether user has any perm for this module. Loading
docs/ref/contrib/admin/index.txt +14 −0 Original line number Diff line number Diff line Loading @@ -1631,6 +1631,19 @@ templates used by the :class:`ModelAdmin` views: be interpreted as meaning that the current user is not permitted to delete any object of this type). .. method:: ModelAdmin.has_module_permission(request) .. versionadded:: 1.8 Should return ``True`` if displaying the module on the admin index page and accessing the module's index page is permitted, ``False`` otherwise. Uses :meth:`User.has_module_perms() <django.contrib.auth.models.User.has_module_perms>` by default. Overriding it does not restrict access to the add, change or delete views, :meth:`~ModelAdmin.has_add_permission`, :meth:`~ModelAdmin.has_change_permission`, and :meth:`~ModelAdmin.has_delete_permission` should be used for that. .. method:: ModelAdmin.get_queryset(request) The ``get_queryset`` method on a ``ModelAdmin`` returns a Loading Loading @@ -1909,6 +1922,7 @@ adds some of its own (the shared features are actually defined in the - :meth:`~ModelAdmin.has_add_permission` - :meth:`~ModelAdmin.has_change_permission` - :meth:`~ModelAdmin.has_delete_permission` - :meth:`~ModelAdmin.has_module_permission` The ``InlineModelAdmin`` class adds: Loading
docs/releases/1.8.txt +3 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,9 @@ Minor features :mod:`django.contrib.admin` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ * ... * :class:`~django.contrib.admin.ModelAdmin` now has a :meth:`~django.contrib.admin.ModelAdmin.has_module_permission` method to allow limiting access to the module on the admin index page. :mod:`django.contrib.auth` ^^^^^^^^^^^^^^^^^^^^^^^^^^ Loading
tests/admin_ordering/tests.py +3 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,9 @@ class MockSuperUser(object): def has_perm(self, perm): return True def has_module_perms(self, module): return True request = MockRequest() request.user = MockSuperUser() Loading