Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django 403 forbidden - redirect to login

Tags:

django

How can I redirect a user to the login page when confronted with a 403 Forbidden?

Consider the following code:

urls.py

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)

urlpatterns = patterns('',
    url(r'^', include(router.urls)),
)

views.py

class UserViewSet(viewsets.ModelViewSet):
        queryset = User.objects.all()
        serializer_class = UserSerializer

        renderer_classes = (renderers.JSONRenderer, renderers.TemplateHTMLRenderer)
        template_name='rest_framework/users.html'

        def list(self, request, *args, **kwargs):
            response = super(viewSet, self).list(request, *args, **kwargs)
            if request.accepted_renderer.format == 'html':
                return Response({'request':request, 'queryset': response.data['results']})
            return response

If I visit /domain/users while not logged in, I'll get a 403 Forbidden error. I would like to instead, redirect to the login page. In other words, never show 403 errors but instead redirect directly to the login page.

I have tried putting:

@login_required
def list(...):

but that does not work. I assume because its inside a viewset.

I have also tried:

def list(...):
    if not request.user.is_authenticated():
        return render_to_response('domain/login.html')

but again, doesn't work.

I tried various 403middlewares but to no avail.

I tried redirecting via the handler403 handler in urls.py

handler403 = 'site.views.login'

No success.

What to do?

Django version: 1.5.4

like image 797
user3417614 Avatar asked Nov 14 '25 18:11

user3417614


1 Answers

You can't use the standard login_required decorator on a class method. You have to either wrap the as_view() when you use it in the URL:

url(r'...', login_required(UserViewSet.as_view()))

or wrap the decorator with django.utils.decorators.method_decorator and apply it to the class dispatch method:

from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required

class UserViewSet(viewsets.ModelViewSet):
...
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
    ....

(see https://docs.djangoproject.com/en/dev/topics/class-based-views/intro/#decorating-class-based-views)

For class-based views you can incorporate this into a reusable PermissionRequiredMixin - see https://stackoverflow.com/a/6455140/839875

Alternatively you can raise a django.core.exceptions.PermissionDenied exception which Django will catch with django.views.defaults.permission_denied

(see https://docs.djangoproject.com/en/1.5/topics/http/views/#the-403-http-forbidden-view)

like image 50
ACGray Avatar answered Nov 17 '25 07:11

ACGray



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!