2012-12-06 14 views
8

Sto veramente cercando di confondere le forme di Django.django formsets confusion (validation, required, empty_permitted)

Sono particolarmente avendo problemi con i seguenti concetti che io non capisco:

Il formset è abbastanza intelligente per ignorare le forme extra che non sono stati cambiato.

Parlare di codice cercando di essere troppo intelligente. Cosa dovrebbe significare esattamente? Perché dovrei anche volerlo?

Poi, cercando di capire il concetto precedente, vedo la gente

rendendo forme nei formsets richiesti.

Questo è un altro concetto di cui non riesco a capire. Che cos'è un modulo richiesto in un formset e perché devo creare un modulo? Ancora qualcosa non documentato.

Quindi, arrivando al mio problema reale, che altre persone sembrano aver avuto, ma non possono davvero spiegare perché l'hanno risolto nel modo in cui l'hanno risolto.

Perché nel seguente esempio, il formset è valido, mentre un singolo modulo con lo stesso input non sarà valido?

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 

Impostazione empty_permitted False sembra dare i risultati attesi per me (che è per il formset per essere validi a causa di mancante 'start' e 'fine'). Questa è un'altra caratteristica non documentata ...

Qualcuno potrebbe risparmiare del tempo per spiegare?

Grazie

risposta

12

Il formset è abbastanza intelligente per ignorare le forme extra che non sono stati modificati.

Parlare di codice cercando di essere troppo intelligente. Cosa dovrebbe significare esattamente? Perché dovrei anche volerlo?

sembra significare - come hai lavorato fuori - che le forme "extra" creati dal formset (con extra=N nel tuo esempio) hanno empty_permitted insieme a True. Have a glance at django/forms/formsets.py per vedere questo accadendo.

formset[0].empty_permitted significa che se formset[0].has_changed() == False, non viene eseguita alcuna ulteriore elaborazione/convalida. Di nuovo, you can see this in action in forms/forms.py.

Per evitare questo, a blog post suggests la definizione di un formset personalizzato da utilizzare in modelformset_factory (o inlineformset_factory) che definisce 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 

non ho ancora testato questo, ma sembra legittimo.

Quanto al perché qualcuno potrebbe desiderare questo, rende l'utilizzo django-dynamic-formset molto più semplice - è possibile inviare i dati per form-0 e form-2 e, assumendo form-1 è stato un modulo aggiuntivo (cioè non legata al modello di dati), Django ha vinto' mi lamento Se empty_permitted erano False per impostazione predefinita, dovresti preoccuparti di saltare il modulo vuoto nel tuo codice o reindirizzare le cose in Javascript.