2014-03-24 71 views
3

如何在遇到403 Forbidden時將用戶重定向到登錄頁面?django 403禁止 - 重定向登錄

考慮下面的代碼:

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 

如果我訪問/域/用戶,而沒有登錄,我會得到一個403 Forbidden錯誤。相反,我想重定向到登錄頁面。換句話說,絕不會顯示403錯誤,而是直接重定向到登錄頁面。

我試圖把:

@login_required 
def list(...): 

,但不起作用。我假設它是在一個視圖裏面。

我也曾嘗試:

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

但同樣,不能正常工作。

我試過各種403middlewares,但無濟於事。

我試圖通過handler403處理程序urls.py

handler403 = 'site.views.login' 

沒有成功重定向。

怎麼辦?

Django的版本:1.5.4

回答

2

不能使用標準login_required裝飾上一個類的方法。你必須要麼包裹as_view()當你在URL中使用它:

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

django.utils.decorators.method_decorator包裹的裝飾,它適用於類dispatch方法:

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): 
    .... 

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

對於基於類的視圖,您可以將其併入可重複使用的PermissionRequiredMixin - 請參閱https://stackoverflow.com/a/6455140/839875

或者,你可以提出一個例外django.core.exceptions.PermissionDenied其中Django會趕上與django.views.defaults.permission_denied

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

+0

這爲我工作。非常感謝你。 class UserViewSet(...) @method_decorator(login_required) def dispatch(self,* args,** kwargs): return super(ProtectedView,self)。派遣(*參數,** kwargs) – user3417614

+0

有一個整潔的混合,你可以用它來做到這一點,已添加到我的答案 – ACGray