2012-12-06 24 views
8

Ich finde wirklich die Django Formsets verwirrend.django formsets Verwirrung (Validierung, erforderlich, empty_permitted)

Ich bin vor allem Probleme mit den folgenden Konzepten, die ich nicht wirklich verstehen:

Die formset klug genug ist extra Formen zu ignorieren, die nicht verändert wurden.

Über den Code sprechen, der versucht, zu intelligent zu sein. Was soll das genau heißen? Warum sollte ich das überhaupt wollen?

Dann versucht, das bisherige Konzept zu verstehen, sehe ich Menschen

Formen in den Formularsätzen erforderlich machen.

Dies ist ein anderes Konzept, das ich nicht verstehen kann. Was ist ein erforderliches Formular in einem Formularsatz und warum muss ich ein Formular erforderlich machen? Wieder etwas nicht dokumentiert.

Dann kommen zu meinem eigentlichen Problem, das andere Leute zu haben scheinen, aber sie können nicht wirklich erklären, warum sie es so repariert haben, wie sie es behoben haben.

Warum im folgenden Beispiel ist das Formset gültig, während ein einzelnes Formular mit der gleichen Eingabe ungültig ist?

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 

auf False empty_permitted Einstellung scheint die erwarteten Ergebnisse für mich zu geben (was für die formset ungültig ist aufgrund fehlender ‚Start‘ und ‚Ende‘). Dies ist ein weiteres undokumentiertes Feature ...

Würde jemand Zeit für die Erklärung haben?

Danke

Antwort

12

Die formset klug genug ist extra Formen zu ignorieren, die nicht verändert wurden.

Über den Code sprechen, der versucht, zu intelligent zu sein. Was soll das genau heißen? Warum sollte ich das überhaupt wollen?

Es scheint zu bedeuten - wie Sie aus gearbeitet - dem „Extra“ Formen der formset erstellt (mit extra=N in Ihrem Beispiel) empty_permitted Satz True haben. Have a glance at django/forms/formsets.py, um dies zu sehen.

formset[0].empty_permitted bedeutet, dass bei formset[0].has_changed() == False keine weitere Verarbeitung/Validierung erfolgt. Wiederum you can see this in action in forms/forms.py.

Um dies, a blog post suggests Definieren eines benutzerdefinierten formset zu verhindern in modelformset_factory (oder inlineformset_factory), die empty_permitted = False setzt zu verwenden:

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

Ich habe nicht getestet, aber es sieht echt.

Wie, warum jemand könnte dies wollen, macht es mit django-dynamic-formset viel einfacher - Sie Daten für form-0 und form-2 und form-1 unter der Annahme, senden kann, wurde eine zusätzliche Form (dh nicht zu modellieren Daten verbunden sind), Django gewonnen‘ t beschweren. Wenn empty_permitted standardmäßig False wäre, müssten Sie sich sorgen, dass Sie das leere Formular in Ihrem eigenen Code überspringen oder Dinge in Javascript neu indizieren.