django - 如何在验证之前处理/清理字段
Posted
技术标签:
【中文标题】django - 如何在验证之前处理/清理字段【英文标题】:django - how to process/clean a field before validation 【发布时间】:2011-06-22 07:07:15 【问题描述】:我有一个表格,只有在清理后才需要验证。
当你运行 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 个字符不,包括a
,我希望form.is_valid()
返回True
!
是否可以在to_python()
之后但在run_validators()
之前运行clean_<fieldname>()
?还是我应该以其他方式这样做?
【问题讨论】:
【参考方案1】:我认为表单验证的过程(及其正确顺序)真的是well documented。
您介意分享您的代码吗?每个表单域上都有一个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
【讨论】:
我添加了一些简化的代码来展示我想要实现的目标。感谢您的帮助。 引发新错误如何阻止当前错误被引发?Edit:
哦,对了,那我可以从现场删除max_length
!对吗?
@Acorn 是的,你可以删除它。我认为是必需的,但这适用于模型。
所以它的要点。我需要在我的clean_<fieldname>()
中进行验证,而不是使用max_length
【参考方案2】:
您可以覆盖 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】:只是添加到 Reiner Gerecke。
当在表单上调用 is_valid() 方法时,MultiEmailField.clean() 方法将作为清理过程的一部分运行,然后它会调用自定义的 to_python() 和 validate() 方法。 Just read the "Form field default cleaning" part and its example
【讨论】:
【参考方案4】:另外,当is_valid()
返回False
时,您可以检查原因,在表单中打印self.errors
。
如果您查看is_valid()
代码,则会检查is_bound
的形式,而self.errors
是否为空
【讨论】:
以上是关于django - 如何在验证之前处理/清理字段的主要内容,如果未能解决你的问题,请参考以下文章