2012-04-26 62 views
7

情況非常簡單: 我正在編寫多用戶博客系統。系統應該阻止非所有者編輯或刪除博客文章。在我看來,我使用通用視圖。將對象級別權限添加到通用視圖

類BlogUpdateView(更新視圖): ...

我知道我應該使用@method_decorator裝飾調度方法。但是,大多數示例僅僅是@method_decorator(login_required)或模型級權限。如何應用對象級別權限來檢查request.user是否是此博客文章的作者? 例如,我嘗試使用django-authority應用程序,並且在此文件中有一個BlogPermission類。我試圖在這個類中定義一個方法,例如

def blog_edit(self, ??, ??)

我應該投入到這個方法?

然後調用此類似: @method_decorator(permission_required('blog_permission.blog_edit(???)'))

我應該傳遞的是什麼?

更新:讀取method_decorator代碼後,我發現它只能接受無參數的函數。我想這就是爲什麼permission_required在這裏不起作用。但是關於這個的工作是什麼?

更新的解決方案:

在分派方法,我檢查用戶權限,然後返回HttpResponseForbidden()如果用戶不符合許可。

+0

您可以檢查您的權限在'get_object'方法。裝飾者用CBV看起來不太好。 – ilvar 2012-04-26 05:33:32

+0

所以你的意思是沒有簡單的方法將對象級別的裝飾器應用到基於類的通用視圖? @ilvar – Xinghan 2012-04-26 13:47:14

+0

我的意思是'get_object'會更容易。爲了讓它更幹,你可以使用'get_object'製作一個Mixin並使用它。 – ilvar 2012-04-26 22:47:52

回答

11

可以使用基於類的視圖做到這一點:

class BlogEdit(UpdateView): 
    model = Blog 

    def dispatch(self, request, *args, **kwargs): 
     if not request.user.has_perm('blog_permission.blog_edit'): 
      return HttpResponseForbidden() 
     return super(BlogEdit, self).dispatch(request, *args, **kwargs) 

    # OR (for object-level perms) 

    def get_object(self, *args, **kwargs): 
     obj = super(BlogEdit, self).get_object(*args, **kwargs) 
     if not obj.user == self.request.user: 
      raise Http404 # maybe you'll need to write a middleware to catch 403's same way 
     return obj 
+2

可以引發內置的異常'django.core.exceptions.PermissionDenied'來顯示來自'get_object'的403錯誤頁面。然後,您可以在'403.html'模板中自定義錯誤,或者在URLconf中使用'handler403'覆蓋視圖(請參閱https://docs.djangoproject.com/en/1.7/topics/http/views/#customizing -error-視圖)。不幸的是,您無法通過異常傳遞消息,並且模板上下文未通過內置行爲傳遞原始異常。如果你想顯示一個特殊的消息,你需要創建中間件。 – jcampbelly 2015-03-07 23:03:48