2014-09-11 151 views
0

我已經創建了一個表單來刪除對象,但我需要檢查想要刪除該對象的用戶是否是創建該對象的用戶。我想檢查它的形式(以及在視圖中),因爲它是一個業務約束。在init,delete或clean方法中,哪裏是檢查的最佳位置?以刪除形式驗證

class DeleteFooForm(forms.ModelForm): 
    class Meta: 
     model = Foo 
     fields = [] 

     def __init__(self, user, *args, **kwargs): 
      super(DeleteFooForm, self).__init__(*args, **kwargs) 
      self.user = user 

     def delete(self): 
      if self.user is not self.instance.user: 
       raise PermissionDenied("Wrong user")   

      self.instance.delete() 

      # more actions, send email, etc. 
+0

在窗體中,您無權訪問請求對象,因此它是驗證權限的錯誤位置。在視圖中執行此操作,並使用消息框架將錯誤刷新到用戶。 – 2014-09-11 13:02:32

+0

我個人建議在'clean()'方法中執行它,因爲它是一種形式約束,它使表單無效(以某種方式)。 – Wolph 2014-09-11 13:04:55

+0

@PauloScardine,我完全不同意。該表格是*絕對*做驗證的合適地點:這就是它的主要用途。沒有理由在兩個不同的地方進行驗證。 – 2014-09-11 13:22:14

回答

1

真的這應該發生在clean方法:這是驗證的地方。這樣做的主要原因是您可以按照正常的方法進行驗證,即引發一個ValidationError,它將被表單API捕獲並顯示爲錯誤。

你當然不希望在__init__中這樣做,因爲即使最初顯示錶格,並且delete爲時已晚,也會引發錯誤。

+0

請注意,表單沒有任何關聯的數據,所以'clean'方法永遠不會被執行(除非我直接執行它)。我不顯示任何東西,我只是使用表單來驗證問題(csrf和用戶),因爲我可能想在刪除對象時添加一些額外的操作。 – Ivan 2014-09-11 14:49:16

+0

@Ivan:我這樣做的方式是在GET請求中使用一個從路徑中獲取對象ID的刪除URL(如'/ foo/123/delete')我顯示一個簡單的是/否確認表單ModelForm)並在POST上調用foo.delete()(如果用戶選擇「是」)。如果用戶不是對象所有者,我會顯示一條消息和一個鏈接返回而不是表單。 – 2014-09-11 17:39:52

+0

如果這是刪除對象的預期方式,那麼Django中將會有一個ModelDeleteForm。 – 2014-09-11 17:57:20