我有一个表格,只有在清理后才需要验证。
运行form.is_valid()
时会发生什么?是否清理了表单,然后验证了表单的已清理版本?
我目前正在采取的行为是,如果我的字段在清理之前没有通过验证,即使清理会通过验证,is_valid()
也会返回False
。
我做错了吗?
# View
class ContactForm(forms.Form):
message = forms.CharField(widget=forms.Textarea, max_length=5)
def clean_message(self):
message = self.cleaned_data['message']
return message.replace('a', '') # remove all "a"s from message
def contact(request):
if request.method == 'POST':
if form.is_valid():
return HttpResponseRedirect('/contact/on_success/')
else:
return HttpResponseRedirect('/contact/on_failure/')
如果邮件少于5个字符不包括form.is_valid()
,我希望True
返回a
!
是否可以在clean_<fieldname>()
之后to_python()
之前运行run_validators()
?或者我应该以其他方式这样做吗?
答案 0 :(得分:33)
我认为表单验证的过程(及其正确的顺序)确实有很好的记录。 http://docs.djangoproject.com/en/dev/ref/forms/validation/#form-and-field-validation
你介意分享你的代码吗?每个表单域都有clean
方法,负责运行to_python
,validate
和run_validators
(按此顺序)。 to_python
接受窗口小部件的原始值,将其强制转换为python类型,validate
获取强制值并运行特定于字段的验证。
根据给定的代码更新了答案
在clean_message
,to_python
以及最重要的validate
之类的所有其他验证运行后, run_validators
被调用。我认为最后一种方法将检查是否违反了max_length
约束。所以你之后更改数据没有任何影响。
解决方案是在这里举起ValidationError
。删除max_length
将避免对输入的长度进行任何验证。
class ContactForm(forms.Form):
message = forms.CharField(widget=forms.Textarea)
def clean_message(self):
message = self.cleaned_data['message']
message = message.replace('a', '') # remove all "a"s from message
if len(message) >= 5:
raise ValidationError('Too many characters ...')
return message
答案 1 :(得分:2)
另外,当is_valid()
返回False
时,您可以检查原因,在表单中打印self.errors
。
如果您查看is_valid()
代码,则会检查表单is_bound
并且self.errors
为空
答案 2 :(得分:0)
您可以覆盖CharField:
class CustomCharField(forms.CharField):
def clean(self, value):
return super().clean(value.replace('a', ''))
然后您可以使用表格
class ContactForm(forms.Form):
message = CustomCharField(widget=forms.Textarea)
答案 3 :(得分:-1)