django自定义表单验证

时间:2010-09-12 17:31:24

标签: python django django-forms

在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

我用干净的方法尝试过它。

2 个答案:

答案 0 :(得分: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是什么。

答案 1 :(得分:3)

如果您没有特定的clean方法,Django仍会验证表单中的所有字段,以确保所有必填字段都存在,必要时它们具有正确的类型,并且选择的字段具有与其中一个选项对应的值。

此表单存在一些问题,可能会导致您的问题。首先,您已覆盖__init__,以便self之后的第一个参数为numbers。但是,当您实例化表单时,您不会传递此参数 - 您只需传递request.POST

其次,像self.fields中一样动态添加字段到__init__是一个坏主意。相反,请使用空number列表声明您的choices字段,并在__init__中设置该字段:

self.fields['number'].choices = numbers