Search code examples
djangodjango-rest-frameworkdjango-authenticationdjango-class-based-viewsdjango-rest-auth

DjangoRestFramework / Django Class Based Views - How to make it redirect to login page if 403 error is raised


These are my views:

# This view is accessed by going to "/CMS/app"
class AppPageView(TemplateView):
    template_name = "app.html"

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(AppPageView, self).dispatch(*args, **kwargs)

# This view is accessed by going to "/user/:user_id"
class user_detail(APIView):
    """
    Get, update or delete a specific user.
    """
    permission_classes = (IsAuthenticated,)

    def get_object(self, pk):
        try:
            return User.objects.get(pk=pk)
        except User.DoesNotExist:
            raise Http404

    def get(self, request, pk):
        user = self.get_object(pk)
        serializer = UserSerializer(user)
        return Response(serializer.data)

When I access either of these views by going to their URLs, I get the default DjangoRestFramework page which says:

User Detail
Get, update or delete a specific user.

GET /CMS/users/8
HTTP 403 FORBIDDEN
Content-Type: application/json
Allow: GET, PUT, DELETE, HEAD, OPTIONS
Vary: Accept

{
    "detail": "Authentication credentials were not provided."
}

Is it possible for me to change it so that instead of showing the default DRF page, make it redirect to the login page? (The login page URL is "/login").

Note: I am using the Django TemplateView for one view and the DRF APIView for the other, but both redirect to the DRF default 403 page when I try to access their URLs without being logged in.


Solution

  • You can add the TemplateHTMLRenderer to your view renderer_classes, this will enable you to use the django 403.html template when an user goes to the url and the user is not authenticated. http://www.django-rest-framework.org/api-guide/renderers/#templatehtmlrenderer

    class user_detail(APIView):
        """
        Get, update or delete a specific user.
        """
        permission_classes = (IsAuthenticated,)
        # Add TemplateHTMLRenderer to your view renderer_classes
        renderer_classes = (JSONRenderer, TemplateHTMLRenderer)
    
        def get_object(self, pk):
            try:
                return User.objects.get(pk=pk)
            except User.DoesNotExist:
                raise Http404
    
        def get(self, request, pk):
            user = self.get_object(pk)
            serializer = UserSerializer(user)
            return Response(serializer.data)