2011-08-17 16 views
7

Mam ModelForm z kilkoma polami. Niektóre pola są wymagane, inne nie. Mam również pole wyboru z różnymi opcjami i chcę, aby niektóre pola były "wymagane" lub nie oparte na tym wyborze pola wyboru.Django modelform usuwa atrybut "wymagany" na podstawie innego pola wyboru

Próbowałem w czystym() metoda Formularza

def clean(self): 
    cleaned_data = self.cleaned_data 
    some_field = cleaned_data.get("some_field") 
    if some_field == 'some_value': 
      self.fields['other_field'].required = False 
    return cleaned_data 

ale to nie działa

Odpowiedz

10

Zobacz dokumentację Django pod numerem Cleaning and validating fields that depend on each other. Standardowa praktyka byłoby wykonać obsługi zamiast następuje:

def clean(self): 
    cleaned_data = self.cleaned_data 
    some_field = cleaned_data.get("some_field") 
    if some_field == 'some_value': 
      # 'other_field' is conditionally required. 
      if not cleaned_data['other_field']: 
       raise forms.ValidationError("'Other_field' is required.") 
    return cleaned_data 
+0

Dzięki. Pomysł ten pomógł mi go zdobyć! – Igor

+0

Muszę wykonać podobną walidację (Django 1.4), ale testowane pole jest tylko do odczytu, więc nie mam go w my cleaned_data (btw - robię to w administratorze). Masz pomysł, jak uzyskać wartość tego pola tylko do odczytu? 10x – Lin

+0

Znaleziono rozwiązanie - form.instance zawiera wszystkie istotne dane, a zmodyfikowane dane są zawarte w formularzu.changed_data – Lin

1

masz prawo pomysł, ale problemem jest to, że poszczególne pola validations już uruchomić przed formie czysty. Masz kilka opcji. Możesz uczynić pole niewymaganym i obsłużyć logikę, kiedy jest ono wymagane w twoim form.clean. Lub możesz opuścić pole zgodnie z wymaganiami i usunąć błędy sprawdzania poprawności, które może wywołać w czystej.

def clean(self): 
    cleaned_data = self.cleaned_data 
    some_field = cleaned_data.get("some_field") 
    if some_field == 'some_value': 
      if 'other_field' in self.errors: 
       del self.errors['other_field'] 
       cleaned_data['other_field'] = None 
    return cleaned_data 

ta ma pewne problemy w tym, że usuwa wszystkie błędy, nie tylko brakujące/wymagany błędów. Występuje również problem z cleaned_data. Masz teraz wymagane pole, którego nie ma w clean_data, dlatego dodałem je jako None. Reszta Twojej aplikacji będzie musiała załatwić tę sprawę. Może wydawać się dziwne, aby mieć wymagane pole, które nie ma wartości.

2

Jeżeli chcesz wydrukować komunikat o błędzie do wymaganego pola w zwykły sposób, można to zrobić:

def clean(self): 
    cleaned_data = super(PasswordChangeForm, self).clean() 
    token = cleaned_data.get('token') 
    old_password = cleaned_data.get('old_password') 
    if not token and not old_password: 
     self._errors['old_password'] = self.error_class([self.fields['old_password'].error_messages['required']]) 
+0

Ta odpowiedź jest naprawdę przydatna! Wielkie dzięki ! – Serafeim

Powiązane problemy