2014-09-11 114 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