diff --git a/django/contrib/auth/mixins.py b/django/contrib/auth/mixins.py index 00fc9cb727..d98c909112 100644 --- a/django/contrib/auth/mixins.py +++ b/django/contrib/auth/mixins.py @@ -79,9 +79,15 @@ class PermissionRequiredMixin(AccessMixin): perms = self.permission_required return perms - def dispatch(self, request, *args, **kwargs): + def has_permission(self): + """ + Override this method to customize the way permissions are checked. + """ perms = self.get_permission_required() - if not request.user.has_perms(perms): + return self.request.user.has_perms(perms) + + def dispatch(self, request, *args, **kwargs): + if not self.has_permission(): return self.handle_no_permission() return super(PermissionRequiredMixin, self).dispatch(request, *args, **kwargs) diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index 29447982f6..e388ec51ee 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -712,6 +712,21 @@ To apply permission checks to :doc:`class-based views :class:`~django.contrib.auth.mixins.AccessMixin` to customize the handling of unauthorized users. + You may also override these methods: + + .. method:: get_permission_required() + + Returns an iterable of permission names used by the mixin. Defaults to + the ``permission_required`` attribute, converted to a tuple if + necessary. + + .. method:: has_permission() + + Returns a boolean denoting whether the current user has permission to + execute the decorated view. By default, this returns the result of + calling :meth:`~django.contrib.auth.models.User.has_perms()` with the + list of permissions returned by :meth:`get_permission_required()`. + Redirecting unauthorized requests in class-based views ------------------------------------------------------