[Solved]-Can PermissionRequiredMixin and LoginRequiredMixin be combined?

3👍

The desired behavior is the default since 2.1, so the other answers are obsolete:

Changed in 2.1: In older versions, authenticated users who lacked permissions were redirected to the login page (which resulted in a loop) instead of receiving an HTTP 403 Forbidden response. [src]

👤tobib

5👍

For many cases raising 403 for unauthenticated users is the expected behaviour. So yes, you need a custom mixin:

class LoggedInPermissionsMixin(PermissionRequiredMixin):
     def dispatch(self, request, *args, **kwargs):
        if not self.request.user.is_authenticated():
            return redirect_to_login(self.request.get_full_path(),
                                     self.get_login_url(), self.get_redirect_field_name())
        if not self.has_permission():
            # We could also use "return self.handle_no_permission()" here
            raise PermissionDenied(self.get_permission_denied_message())
        return super(LoggedInPermissionsMixin, self).dispatch(request, *args, **kwargs)

3👍

I wanted to add a comment, but my reputation does not allow. How about the following? I feel the below is more readable?

Updated after comments

My reasoning is: You basically write modified dispatch from LoginRequiredMixin and just set raise_exception = True. PermissionRequiredMixin will raise PermissionDenied when correct permissions are not met

class LoggedInPermissionsMixin(PermissionRequiredMixin):
    raise_exception = True

    def dispatch(self, request, *args, **kwargs):
        if not self.request.user.is_authenticated():
            return redirect_to_login(self.request.get_full_path(),
                                     self.get_login_url(),
                                     self.get_redirect_field_name())
        return super(LoggedInPermissionsMixin, self).dispatch(request, *args, **kwargs)

3👍

Simplest solution seems to be a custom view mixin.
Something like that:

class PermissionsMixin(PermissionRequiredMixin):
    def handle_no_permission(self):
        self.raise_exception = self.request.user.is_authenticated()
        return super(PermissionsMixin, self).handle_no_permission()

Or, just use PermissionRequiredMixin as usual and put this handle_no_premission to every CBV.

Leave a comment