2009-05-29 58 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