2010-12-19 18 views
11

我正在使用Django表单。我在验证模型层:如何在我的Django的views.py中引发ValidationError(或者做类似的事情)?

def clean_title(self): 
    title = self.cleaned_data['title'] 
    if len(title) < 5: 
     raise forms.ValidationError("Headline must be more than 5 characters.") 
    return title 

不过,也有一些事情,我需要在views.py验证。例如...是用户最后一次发布超过一分钟前的内容吗?

这种东西需要request.user,模型层无法获取。所以,我必须在views.py中进行验证。我如何在views.py中做一些事情来做到这一点?

raise forms.ValidationError("Headline must be more than 5 characters.") 
+1

这看起来不像是在模型层验证(如在django.db.models.Model中。你的意思是django.forms.Form/ModelForm层?我猜是这样的 – 2010-12-19 10:02:43

+0

我有一个类似的要求,原因不同:有一个字段只是有时需要,这取决于页面,所以视图需要强制执行它,因为它与页面紧密耦合。 – 2014-07-31 07:14:50

回答

12

我认为gruszczy的答案是一个很好的答案,但是如果您在涉及变量的泛型验证后,您认为这些变量只在视图中可用,则可以使用以下替代方法:将变量作为参数传递给表单并处理在表单的主要clean()方法中。

这里的差异/优势是您的视图保持简单,并且所有与可接受的表单内容相关的事情都发生在表单中。

如:

# IN YOUR VIEW 
# pass request.user as a keyword argument to the form 
myform = MyForm(user=request.user) 


# IN YOUR forms.py 
# at the top: 

from myapp.foo.bar import ok_to_post # some abstracted utility you write to rate-limit posting 

# and in your particular Form definition 

class MyForm(forms.Form) 

    ... your fields here ... 

    def __init__(self, *args, **kwargs): 
     self.user = kwargs.pop('user') # cache the user object you pass in 
     super(MyForm, self).__init__(*args, **kwargs) # and carry on to init the form 


    def clean(self): 
     # test the rate limit by passing in the cached user object 

     if not ok_to_post(self.user): # use your throttling utility here 
      raise forms.ValidationError("You cannot post more than once every x minutes") 

     return self.cleaned_data # never forget this! ;o) 

注意的是,在clean()方法提高通用ValidationError将会把错误变成myform.non_field_errors所以你必须确保你的模板中包含{{form.non_field_errors}}如果您要手动显示窗体

+0

伟大的解决方案。这是黑客吗?我喜欢它,但是 – TIMEX 2010-12-19 12:42:08

+0

不,我不会称它为黑客。它只是利用Django Form类比默认/教程方法更多。我已经使用了很多地方和(只要你知道pop()会做什么,因为它从kwargs中删除了关键字参数,没有什么可以吸引你。如果你不想删除它从kwargs中,使用get()来代替。 – 2010-12-19 12:46:45

4

在视图中不使用ValidationError,因为这些例外与表单一样。相反,你应该将用户重定向到其他网址,这将向他解释,他不能很快发布。这是处理这件事的正确方法。 ValidationError应当在Form实例内引发,当输入数据无效时。不是这种情况。

+0

我认为这是一个好方法,但从可用性的角度来看,只需将该消息添加为flash/django.contrib.messages消息并*不*重定向到新页面即可,而只是渲染填好的表格再次填写。这样,用户可以等待例如50秒,并再次提交数据,而无需重新键入全部 – 2010-12-19 10:17:02

相关问题