Django自定义表单验证
在Django/Python中,当你创建一个自定义表单时,是否需要添加一个clean()方法,还是调用.is_valid()就会自动进行默认的验证呢?
if request.method == 'POST':
filter = FilterForm(request.POST)
if filter.is_valid():
print 'Month is ' + filter.cleaned_data['month']
print 'Type is ' + filter.cleaned_data['type']
print 'Number is ' +filter.cleaned_data['number']
else:
print 'Invalid form'
print filter.errors
虽然显示了“无效表单”,但没有任何错误信息被打印出来。
class FilterForm(forms.Form):
months = [('January','January'),
('February','February'),
('March','March'),
('April','April'),
('May','May'),
('June','June'),
('July','July'),
('August','August'),
('September','September'),
('October','October'),
('November','November'),
('December','December'),]
types = [('text','Text'),
('call','Call'),]
month = forms.ChoiceField(months)
type = forms.ChoiceField(choices=types,widget=forms.CheckboxSelectMultiple)
def __init__(self,numbers,*args, **kwargs):
super(FilterForm,self).__init__(*args, **kwargs)
self.fields['number'] = forms.ChoiceField(choices=numbers)
def clean(self):
return self.cleaned_data
我试过有和没有clean方法的情况。
2 个回答
3
如果你没有特别定义的 clean
方法,Django 还是会检查你表单里的所有字段,确保所有必填字段都有填写,类型也正确,并且那些有选项的字段值是选项中的一个。
这个表单有几个问题可能导致你遇到的麻烦。首先,你重写了 __init__
方法,让 self
后面的第一个参数变成了 numbers
。但是,当你创建这个表单的时候,并没有传入这个参数,你只传了 request.POST
。
其次,在 __init__
方法里动态添加字段到 self.fields
是个坏主意。更好的做法是先声明你的 number
字段,并把 choices
列表留空,然后在 __init__
方法里再设置它:
self.fields['number'].choices = numbers
3
是否需要有一个 clean() 方法?
不需要,完全是可选的。
Django 在验证表单时,会按照特定的顺序做很多事情。你可以在这里了解这个过程:
http://docs.djangoproject.com/en/dev/ref/forms/validation/
至于如何找到你的问题,如果你在模板中加上 {{form.errors}}
,你就能看到哪个字段出错了。我觉得可能是你的选择定义在了一个地方,导致某些东西在需要的时候无法找到它(把它们移出类)。
编辑:差点漏掉这个。看看这一行:
def __init__(self,numbers,*args, **kwargs)
然后再看看这一行:
filter = FilterForm(request.POST)
这次你也需要传递 numbers
参数。这是一个全新的实例,它无法验证,因为它不知道 numbers
是什么。