2017-11-27 4 views
0

Ich verstehe nicht, warum ist mein Modell clean Methode vor der vollständigen Form Validierung aufgerufen.Django: Modell sauber Methode genannt vor Form sauber

Ich habe Felder in meinem Formular benötigt. Wenn ich sie nicht fülle, erhalte ich keine Formfehler, statt dessen wird die Model-Clean-Methode aufgerufen (also nehme ich an, weil save aufgerufen wird).

Es stürzt in Modellen clean() Methode:

if self.date_from > self.date_to 

kann datetime.date zu NoneType nicht vergleichen

Weil ich nicht date_to Feld ausgefüllt haben. Ich denke, dass Form sollte damit umgehen und erhöhen ValidationError und Modelle save() sollte nicht einmal aufgerufen werden.

Create View sollte form_invalid Methode erben.

class TripCreationForm(forms.ModelForm): 
    date_from = forms.DateField(required=True) 
    date_to = forms.DateField(required=True) 
    place_id = forms.CharField(widget=forms.HiddenInput(),required=True) 


    class Meta: 
     model = Trip 
     fields = ['date_from','date_to','detail','participants','place_id'] 

    def __init__(self, *args,**kwargs): 
     user = kwargs.pop('user') 
     super(TripCreationForm, self).__init__(*args,**kwargs) 
     fs_helpers.add_widget_attribute('class','datepicker',self.fields['date_from']) 
     fs_helpers.add_widget_attribute('class','datepicker',self.fields['date_to']) 
     self.instance.user = user 

    def clean(self): 

     cleaned_data = super(TripCreationForm,self).clean() 
     city, created = City.objects.get_or_create(place_id=self.cleaned_data['place_id']) 
     self.instance.city = city 
     date_from = self.cleaned_data.get('date_from') 
     date_to = self.cleaned_data.get('date_to') 
     if date_from and date_to and date_from>=date_to: 
      raise ValidationError(_('Date from can\'t be higher that date to')) 

     return cleaned_data 

Das ist meine Ansicht:

class TripCreationView(SuccessMessageMixin,CreateView): 
    form_class = TripCreationForm 
    template_name = 'trips/add_new_trip.html' 
    success_message = _('Congratulations! You\'ve added a new trip!') 
    context_object_name = 'trip_creation_form' 

    def post(self, request, *args, **kwargs): # TODO Switch to get_success_url 
     return super(TripCreationView, self).post(self, request, *args, **kwargs) 

    def get_form_kwargs(self): 
     kwargs = super(TripCreationView, self).get_form_kwargs() 
     kwargs['user'] = self.request.user 
     return kwargs 

    def get_context_data(self, **kwargs): 
     context= super(TripCreationView,self).get_context_data(**kwargs) 
     context['trip_creation_form'] = context['form'] 
     return context 

    def get_success_url(self): 
     return self.request.POST.get('success_url') or reverse('frontend:homepage' 

)

Und dieser Teil des Modells ist:

def save(self, *args, **kwargs): 
    created = not (bool(self.pk)) 
    self.full_clean() 
    with transaction.atomic(): 
     Trip.objects.stretch_trips(self) 
     super(Trip, self).save(*args, **kwargs) 

def clean(self): 
    if self.date_from > self.date_to: # HERE IT CRASHES 
     raise ValidationError(_("Date to can't be lower than date from")) 

Wo liegt das Problem? Warum gibt es keinen Form-Clean-Fehler?

Antwort

2

Wenn ein model form is validated, führt es die clean Methode für das Modell. Wenn Sie sich das vollständige Traceback ansehen, das Sie nicht enthalten haben, dann werden Sie feststellen, dass der Fehler auftritt, wenn die Ansicht form.is_valid() aufruft, nicht, wenn das Formular gespeichert wird.

In der clean-Methode Ihres Modells sollten Sie überprüfen, dass self.date_from und self.date_to festgelegt sind, ähnlich der sauberen Methode Ihres Formulars.

class Trip(models.Model): 
    def clean(self): 
     if self.date_from and self.date_to and self.date_from > self.date_to:     raise ValidationError(_("Date to can't be lower than date from")) 

Sie könnten die Kontrolle aus der clean Methode, die Form entfernen Doppelarbeit zu vermeiden.

+0

Danke. Date_from und date_to sind erforderliche Modellfelder. Ich vermute also, dass es überprüft wird, bevor die Modelle sauber werden. –