Django自定义表单验证

0 投票
2 回答
2483 浏览
提问于 2025-04-16 04:03

在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 是什么。

撰写回答