2017-01-18 25 views
0

我不是很舒服地使用基於類的視圖,但我知道他們的特權,所以我迫使自己開始更頻繁地使用它們。基於類的視圖:在哪裏檢查權限?

有這個視圖接收路徑參數:manage/:id管理一個特定的實體。

class MyView(TemplateView): 
    template_name = '...' 

    def get_context_data(self, **kwargs): 
    context = super(MyView, self).get_context_data(**kwargs) 
    context['entity'] = get_object_or_404(Entity, pk=self.args[0]) 
    return context 

Entity包括授權用戶執行特殊操作的列表。這種觀點,MyView是這些特殊行動之一。

我試着製作一個裝飾器的視圖,但它需要首先找到Entity,所以我不知道如何解決這個問題。

現在,我有一個check_permission(request, entity)函數,檢查當前用戶是否是這些授權的用戶之一。

我的問題是我應該在基於類的視圖中調用此函數,如MyView哪些視圖會被視爲「特殊操作」?

我應該只從get_context_data()打電話嗎?

回答

1

將它寫入dispatch()。它看起來是這樣的:

class MyView(TemplateView): 
    template_name = '...' 

    def dispatch(self, request, *args, **kwargs): 
     entity = get_object_or_404(Entity, pk=args[0]) 
     if not check_permission(request, entity): 
      raise Http404 
     return super(MyView, self).dispatch(request, *args, **kwargs) 
+0

我在哪裏檢索「實體」?我是否需要'dispatch'和'get_context_data'中的'get_object_or_404'? – dabadaba

+0

'entity'是'Entity'的一個實例嗎?無法記住從頭開始,但是您將獲得獲取數據所需的數據(與在'get_context_data()')中執行相同的操作,無論是在* args'和'** kwargs'還是'self.args'和'self.kwargs' – yedpodtrzitko

+0

當然,這是我的顧慮,我需要得到它兩次?是不是可能只是'get_object_or_404(Entity,pk = self.args [0])'一次? – dabadaba

0

Django Braces看看,這是一個堅實的一套圍繞權限設計混入的。

你如何專門處理權限很大程度上取決於實現。我在dispatch()中做過,之前是Braces做它的方式,但是如果它是特定於對象或查詢集的,我會在實際的get_object或get_queryset方法中作爲DetailView的一部分來完成它。

例如,如果您的創建者與實體關聯,則可以覆蓋get_object以檢查當前登錄的用戶是實體的創建者。

class EntityView(LoginRequiredMixin, DetailView): 
    model = Thing 

    def get_object(self, **kwargs): 
     return Entity.objects.get_object_or_404(
      pk=kwargs['entity_id'], 
      creator=self.request.user 
     ) 

注意:LoginRequiredMixin是大括號的一部分。很光滑。

0

您可以檢查dispatch的權限,如yedpodtrzitko所說。我認爲把它放在一個可以放在你的視圖中的mixin中也是一個好主意。

下面是一個例子:

from django.core.exceptions import PermissionDenied 


class ViewPermissionsMixin(object): 
    """Base class for all custom permission mixins to inherit from""" 
    def has_permissions(self): 
     return True 

    def dispatch(self, request, *args, **kwargs): 
     if not self.has_permissions(): 
      raise PermissionDenied 
     return super(ViewPermissionsMixin, self).dispatch(
      request, *args, **kwargs) 

class MyCustomPermissionMixin(ViewPermissionsMixin): 

    def has_permissions(self): 
     # here you will have access to both 
     # self.get_object() and self.request.user 
     return self.request.user in self.get_object().special_list_of_people 

現在你可以扔在你看來MyCustomPermissionMixin

class MyView(MyCustomPermissionMixin, TemplateView): 
    # ... 

在你的情況下,由於您使用的是TemplateView,你也應該做出get_object()方法返回你想要處理的對象。模板視圖默認情況下沒有此方法。

最後,只是想說,一旦你瞭解了更多關於如何使用它們的信息,你就會喜歡Django的基於類的視圖。