2016-07-21 4 views
0

Wie mache ich entweder erste oder zweite Attribut in Formular erforderlich? In diesem Formular möchte ich, dass Benutzer text_to_translate oder file ausfüllen. Ich habe versucht, clean_something für beide Attribute zu erstellen, aber es scheint nicht zu funktionieren. Es stellt sich -Machen Sie entweder x oder y Attribut in Formular erforderlich

KeyError Ausnahmewert: ‚Datei‘

Es ist wahrscheinlich, weil, wenn die clean_text_to_translate Methode aufgerufen wird, die file noch nicht gereinigt.

Wissen Sie, was zu tun ist?

class NewOrderForm(forms.ModelForm): 
    text_to_translate = forms.CharField(widget=forms.Textarea(attrs={'placeholder': 'Specification'}), required=False) 
    file = forms.FileField(required=False) 
    delivery_date = forms.DateField(label='Deadline', widget=SelectDateWidget(years=[y for y in range(1930, 2050)])) 

    class Meta: 
     model = Job 
     fields = (
      'short_description', 'language_from', 'text_to_translate', 'file', 'notes','style', 'delivery_date', 
     ) 
     widgets = { 
      'text_to_translate': forms.Textarea(attrs={'class': 'form-control'}), 
      'language_from': forms.Select(attrs={'class': 'dropdown'}) 
      # 'level':forms.Select(attrs={'class': 'form-control'}), 

     } 


    def clean_text_to_translate(self): 
     if self.cleaned_data['file'] is None: 
      return self.cleaned_data['file'] 
     return ValidationError('You can fill either text to translate or attach a file') 

    def clean_file(self): 
     if self.cleaned_data['text_to_translate']=='': 
      return self.cleaned_data['text_to_translate'] 
     return ValidationError('You can fill either text to translate or attach a file') 

Antwort

3

Sie validieren zwei Felder, die voneinander abhängig sind - dies ist in der documentation beschrieben. Die Dokumentation empfiehlt, die Validierung in der clean() -Methode des Formulars auszuführen:

Wir führen eine Validierung für mehrere Felder gleichzeitig durch, daher ist die clean() -Methode des Formulars dafür ein guter Ausgangspunkt.

In diesem Moment können Sie die Werte zur Verfügung haben alle, dass die einzelnen Felder Validierung überlebt - so denken Sie daran, dass text_to_translate und file leer sein kann - Zugriff auf diese Werte nicht eckige Klammer-Notation verwenden cleaned_data.get() statt. Ihre clean() Methode könnte so aussehen: using {{ form.non_field_errors }} in Ihrer Vorlage

def clean(self): 
     cleaned_data = super(NewOrderForm, self).clean() 
     file = cleaned_data.get("file") 
     text_to_translate = cleaned_data.get("text_to_translate") 
     if file and text_to_translate: # both fields were filled 
      raise forms.ValidationError("You must provide either text or file, not both.") 
     elif not (file or text_to_translate) # neither one was filled 
      raise forms.ValidationError("You must provide either text or file") 

natürlich, müssen Sie diesen Fehler angezeigt werden soll.

+0

Danke, ich verstehe Ihren Vorschlag und werde ihn benutzen, aber es ist wahrscheinlich ein kleiner Fehler. Ich meinte xor - eins und nur eines der beiden Felder sollte ausgefüllt werden. –

+0

Ich sehe, ich habe meine Antwort entsprechend bearbeitet. – rafalmp

Verwandte Themen