2011-01-01 9 views
3

Ich verwende Django und habe ein Formular mit zwei zusätzlichen Inline-Formatzeichen. Ich möchte überprüfen, dass jedes Formularset mindestens ein ausgefülltes Formular enthält. Ich habe Code so geschrieben, dass das funktioniert, aber es funktioniert nur für jedes Formset auf einmal. Wenn ich das Formular übergebe, ohne dass Formset-Formulare ausgefüllt sind, wird nur der erste einen Validierungsfehler angezeigt. Wenn ich dann das erste Formset-Formular ausfüllen und das zweite Formular leer lassen, wird das zweite Formular fehlerhaft.Django Inline Formset Benutzerdefinierte Validierung validiert nur einzelne Formsets zu einem Zeitpunkt

Ich möchte Fehler auf beiden Formularen angezeigt werden, wenn beide nicht gültig sind.

Die Formulare sind nur Standard ModelForm Instanzen. Hier ist meine Ansicht:

class RequiredBaseInlineFormSet(BaseInlineFormSet): 
    def clean(self): 
     self.validate_unique() 
     if any(self.errors): 
      return 
     if not self.forms[0].has_changed(): 
      raise forms.ValidationError("At least one %s is required" % self.model._meta.verbose_name) 

def create(request): 
    profile_form = ProfileForm(request.POST or None) 
    EmailFormSet = inlineformset_factory(Profile, Email, formset=RequiredBaseInlineFormSet, max_num=5, extra=5, can_delete=False) 
    email_formset = EmailFormSet(request.POST or None) 
    PhoneFormSet = inlineformset_factory(Profile, Phone, formset=RequiredBaseInlineFormSet, max_num=5, extra=5, can_delete=False) 
    phone_formset = PhoneFormSet(request.POST or None) 
    if profile_form.is_valid() and email_formset.is_valid() and phone_formset.is_valid(): 
     profile = profile_form.save() 
     emails = email_formset.save(commit=False) 
     for email in emails: 
      email.profile = profile 
      email.save() 
     phones = phone_formset.save(commit=False) 
     for phone in phones: 
      phone.profile = profile 
      phone.save() 
     messages.add_message(request, messages.INFO, 'Profile successfully saved') 
    return render_to_response(
     'add.html', { 
      'profile_form': profile_form, 
      'email_formset': email_formset, 
      'phone_formset': phone_formset 
     }, context_instance = RequestContext(request) 
    ) 

Und hier ist meine Vorlage des Formulars, einhüllen es nützlich ist:

<form action="" method="post" accept-charset="utf-8"> 
    {{ email_formset.management_form }} 
    {{ phone_formset.management_form }} 
    {{ profile_form|as_uni_form }} 
    <div class="formset-group" id="email_formset"> 
     {{ email_formset.non_form_errors }} 
     {% for email_form in email_formset.forms %} 
      <div class='form'> 
       {{ email_form|as_uni_form }} 
      </div> 
     {% endfor %} 
    </div> 
    <div class="formset-group" id="phone_formset"> 
     {{ phone_formset.non_form_errors }} 
     {% for phone_form in phone_formset.forms %} 
      <div class='form'> 
       {{ phone_form|as_uni_form }} 
      </div> 
     {% endfor %} 
    </div> 
    <input type="submit" value="Save Profile" id="submit"> 
</form> 

Antwort

2

Aufruf der is_valid() -Funktion für jedes Formular, das Sie Validierung wollen auftreten. In Ihrem Beispiel tun Sie, wenn a.is_valid und b.is_valid anc c.is_valid ... Wenn a falsch ist, werden b und c nie aufgerufen. Versuchen Sie etwas anderes, wie:

alpha=a.is_valid() 
beta=b.is_valid() 
gamma=c.is_valid() 

if alpha and beta and gamma: 
    do stuff 
+0

Ich denke, du hast Recht. Ich hatte das verlassen, aber jetzt komme ich zurück und ich hatte einige Erfolge, indem ich alle Formsets in eine Liste setzte und mit 'all()' z. 'if profile_form.is_valid() und all ([fs.is_valid() für fs in Formsets]):' Danke für die Eingabe. –

Verwandte Themen