Search code examples
djangodjango-1.9

Can PermissionRequiredMixin and LoginRequiredMixin be combined?


I have some users that are allowed to see a certain view.

To allow users to login and complain with a 403 Forbidden for those users that cannot see that login, I can use the following (as explained here):

@permission_required('polls.can_vote', raise_exception=True)
@login_required
def my_view(request):
    ...

This indeed works as expected. But all my views are class-based views. Since Django 1.9 (finally!) there are a bunch of pretty mixins for doing things that were only possible through the decorators. However...

class MyClassView(LoginRequiredMixin, PermissionRequiredMixin, TemplateView):
    raise_exception = <???>
    permission_required = 'polls.can_vote'
    template_name = 'poll_vote.html'

this doesn't work. Because the raise_exception flag is used by both LoginRequiredMixin and PermissionRequiredMixin, I cannot set it to anything.

  • if raise_exception is True, a user that is not logged in receives a 403 Forbidden (which I do not want).
  • if raise_exception is False, a user that is not allowed to see the view, will be redirected to the login page which, because the user is logged in, will redirect again to the page. Creating a not-at-all fancy redirect loop.

Of course I could implement my own mixin that behaves I expected, but is there any Django-way of doing this in the view itself? (not in the urls.py)


Solution

  • 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]