如何在Django的views.py中引发ValidationError?
我在使用Django的表单功能。我在模型层进行验证:
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.")
3 个回答
6
你可以在视图中使用消息:
from django.contrib import messages
messages.error(request, "Error!")
文档链接:https://docs.djangoproject.com/es/1.9/ref/contrib/messages/
9
在视图中你不应该使用 ValidationError
,因为这个错误主要是用在表单里的。相反,你应该把用户重定向到另一个网址,告诉他们不能这么快再提交。这样处理问题才是正确的。ValidationError
应该在 Form
实例中被触发,当输入的数据不符合要求时才用到。这种情况并不适用。
27
我觉得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}}
。