2013-04-05 70 views
0

我最近在我的Django應用程序中切換到基於類的視圖,並希望儘可能優雅地使用它們。在應用程序中,我有一個評論系統,如果權限匹配,管理員應該能夠刪除和/或發佈/取消發佈評論。我寫了一個RedirectView,包括功能:在django的同一個基於類的視圖中使用不同的權限裝飾器

class CommentChangeView(RedirectView, SingleObjectMixin): 
    """ 
    A redirection that acts on a Comment. The url parameter 
    "action" is taken as a class function and executed. 
    """ 

    model = Comment 


    def get_redirect_url(self, pk): 
     """ 
     Redirect to the article page, always. 
     """ 
     return reverse('post', args=(self.object.post.slug,)) 


    def get(self, *args, **kwargs): 
     """ 
     Here, it is decided what to execute. 
     """ 

     self.object = self.get_object() 
     func = getattr(self, kwargs.pop('action', None), None) 

     if callable(func): 
      func() 

     return super(CommentChangeView, self).get(*args, **kwargs) 

    @method_decorator(permission_required('blog.delete_comment')) 
    def delete(self): 
     """ 
     Delete the comment 
     """ 

     self.object.delete() 
     messages.success(self.request, 'Comment deleted.') 

    @method_decorator(permission_required('blog.change_comment')) 
    def toggle_publish(self): 
     """ 
     Toggle its publication state 
     """ 

     self.object.published = not self.object.published 
     self.object.save() 
     messages.success(self.request, 'Comment toggled.') 

現在的問題是,我想這兩個動作有不同的權限 - 因此不同的裝飾。通常,dispatch函數是裝飾的。上面的代碼不起作用,我得到TypeError。沒有裝飾者,它完美的作品。

我該如何實施這種情況?還是應該分開刪除和發佈的意見?


這裏是TypeError的堆棧跟蹤:

Internal Server Error: /comment/toggle_publish/1/ 
Traceback (most recent call last): 
    File "/***/lib/python2.7/site-packages/django/core/handlers/base.py", line 115, in get_response 
    response = callback(request, *callback_args, **callback_kwargs) 
    File "/***/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view 
    return self.dispatch(request, *args, **kwargs) 
    File "/***/lib/python2.7/site-packages/django/views/generic/base.py", line 86, in dispatch 
    return handler(request, *args, **kwargs) 
    File "/***/blog/blog/views.py", line 186, in get 
    func() 
    File "/***/lib/python2.7/site-packages/django/utils/decorators.py", line 25, in _wrapper 
    return bound_func(*args, **kwargs) 
TypeError: _wrapped_view() takes at least 1 argument (0 given) 
+1

您應該發佈'TypeError'的回溯。 *可能*有助於調試。 – 2013-04-05 22:04:44

回答

0

Bibhas指出我到正確的方向上,更加緊密地看着堆棧跟蹤。通過引入一個額外的函數參數,我能夠得到它的工作。此代碼現在可用:

class CommentChangeView(RedirectView, SingleObjectMixin): 
    """ 
    A redirection that acts on a Comment. The url parameter 
    "action" is taken as a class function and executed. It therefore 
    combines the delete and publish_comment functions (and, later, possibly) 
    more. 
    """ 

    model = Comment 


    def get_redirect_url(self, pk): 
     """ 
     Redirect to the article page, always. 
     """ 
     return reverse('post', args=(self.object.post.slug,)) 


    def get(self, request, *args, **kwargs): 
     """ 
     Here, it is decided what to execute. 
     """ 

     self.object = self.get_object() 
     func = getattr(self, kwargs.pop('action', None), None) 

     if callable(func): 
      func(request) 

     return super(CommentChangeView, self).get(request, *args, **kwargs) 

    @method_decorator(permission_required('blog.delete_comment')) 
    def delete(self, request): 
     """ 
     Delete the comment 
     """ 

     self.object.delete() 
     messages.success(self.request, 'Comment deleted.') 

    @method_decorator(permission_required('blog.change_comment')) 
    def toggle_publish(self, request): 
     """ 
     Toggle its publication state 
     """ 

     self.object.published = not self.object.published 
     self.object.save() 
     messages.success(self.request, 'Comment toggled.') 
相關問題