2012-12-06 48 views
8

我真的發現django formsets令人困惑。django formsets混淆(驗證,必填,empty_permitted)

我特別有以下概念的問題,我真的不明白:

的表單集是足夠聰明忽略不 改變額外的形式。

談論代碼太過聰明。這究竟意味着什麼?爲什麼我甚至想要那樣?

然後,試圖瞭解以前的概念,我看到人們

使得在所需的表單集形式。

這是另一個我無法理解的概念。什麼是formset中的必需表單,爲什麼我必須要求表單?再次沒有記錄的東西。

然後來到我的實際問題,其他人似乎有,但他們不能真正解釋他們爲什麼修復它,以他們的方式修復它。

爲什麼在下面的例子中,formset是有效的,而具有相同輸入的單個表單將是無效的?

import django 
class MyForm(django.forms.Form): 
    start = django.forms.DateField() 
    end = django.forms.DateField() 

data = { 
    'form-TOTAL_FORMS': '1', 
    'form-MAX_NUM_FORMS': '', 
    'form-INITIAL_FORMS': '0', 
    'form-0-start': '', 
    'form-0-end': '', 
} 

MyFormSet = formset_factory(MyForm) 
formset = MyFormSet(data) 
#fee_forms[0].empty_permitted = False 

print formset.is_valid() 
# --- returns True --- 
print formset.errors 

f = MyForm({'start': '', 'end': ''}) 
print f.is_valid() 
# --- returns False --- 
print f.errors 

設置已empty_permitted爲False,似乎給了預期的結果對我來說(這是該formset是無效的,由於缺少「開始」和「結束」)。這是另一個無證的功能...

有人會抽出一些時間來解釋嗎?

謝謝

回答

12

的表單集是足夠聰明,忽略不改變額外的形式。

談論代碼太過聰明。這究竟意味着什麼?爲什麼我甚至想要那樣?

這似乎意味着 - 你摸索出 - 由表單集(與extra=N在你的例子)創建的「額外」的形式有empty_permitted設置爲TrueHave a glance at django/forms/formsets.py看到這種情況發生。

formset[0].empty_permitted意味着如果formset[0].has_changed() == False沒有進一步的處理/驗證完成。再次,you can see this in action in forms/forms.py

爲了防止這種情況a blog post suggests定義自定義表單集在modelformset_factory(或inlineformset_factory)來使用這臺empty_permitted = False

class MyModelFormSet(BaseModelFormSet): 
    def __init__(self, *args, **kwargs): 
     super(MyModelFormSet, self).__init__(*args, **kwargs) 
     for form in self.forms: 
      form.empty_permitted = False 

我沒有測試過這一點,但它看起來合法的。

至於爲什麼有人會想這樣,它使得使用 django-dynamic-formset要簡單得多 - 你可以爲form-0form-2和發送數據,假設form-1是一個額外的形式(沒有鏈接到數據模型),Django會贏得」 t抱怨。如果empty_permitted默認爲False,那麼您不得不擔心在自己的代碼中跳過空白表單,或者在Javascript中重新編制事物。