2009-05-29 82 views
10

在我的Django应用程序应用程序中,我有一个从简单(非模型)窗体创建的formset,额外= 1(以允许javasript稍后添加更多窗体)。Django Formset.is_valid()失败的额外形式

class SomeForm(forms.Form): 
    #some fields with required=False 
    length = forms.IntegerField(required=False) 

    # An example of one of the fields with choices i have 
    A = 0 
    B = 1 
    C = 2 
    D = 3 

    choices = ((A, 'Aah'), (B, 'Baa'), (C, 'Caa'), (D, 'Daa')) 

    # This is a required choice field 
    pickme = forms.ChoiceField(choices=choices) 


SomeFormset = formset_factory(SomeForm, can_delete=True, extra=1) 

现在,当我创建并尝试验证它在我看来,在POST请求:

my_formset = SomeFormset(request.POST, request.FILES) 

if(my_formset.is_valid()): 
    # FAIL 

它总是失败上述检查中,如果额外呈现的表单提交空。

如果我在最后一个空的额外表格上检查form.changed_data,我会得到可以选择的字段(例如上面的pickme)。 换句话说,当需要一些选择字段时,formset不够聪明,以致于无法确定空的提交表单应该被忽略。

回答

18

谢谢卡尔, 你让我发现了我的问题的根源。

当创建一个选择字段,这是必需的,我们必须设置一个初始一种形式,否则表单会考虑现场改变

因此,对于这样的形式:

class SomeForm(forms.Form): 

    A = 0 
    B = 1 
    C = 2 
    D = 3 

    choices = ((A, 'Aah'), (B, 'Baa'), (C, 'Caa'), (D, 'Daa')) 

    # This is a required choice field 
    pickme = forms.ChoiceField(choices=choices) 

我们这样做:

pickme = forms.ChoiceField(choices=choices, initial=A) 

然后当一个formset检查额外的形式,它会看到pickme有A的初始值,现在也是A,并且会认为它没有变化。

9

这不是通常的formset行为。 Formsets pass empty_permitted=True to all "extra" formsa form with empty_permitted that hasn't been modified should always pass validation。请注意,这在Django管理员(如果使用内联)中工作得很好。

你必须在你的代码中做别的事情来打破这种行为。发布相关表格的完整代码?

+0

谢谢我会研究它并回复你 – drozzy 2009-05-30 02:43:13

+0

这是由于选择字段,因为forms.changed_data包含所有我没有“空”条目的选择字段。我更新了这个问题以反映这一点。尽管如此,我仍然没有一个好的解决方案。 – drozzy 2009-06-01 12:55:08