2017-11-27 11 views
0

私のモデルcleanメソッドがフルフォーム検証の前に呼び出されたのはなぜですか?Django:フォームクリーンアップの前に呼び出されたモデルクリーンメソッド

私のフォームには必須のフィールドがあります。私がそれらを埋めるのではなく、私はフォームのエラーを取得するのではなく、モデルのクリーンメソッドが呼び出されます(saveが呼び出されていると思います)。

それはモデルclean()方法でクラッシュ:私はdate_toフィールドを埋めていなかったので

if self.date_from > self.date_to 

がNoneType

にdatetime.dateを比較することはできません。私はフォームがそれを処理しなければならないと思うし、ValidationErrorとモデルsave()を呼び上げてもいけません。

ビューを作成するには、form_invalidメソッドを継承する必要があります。

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 

は、これが私の見解です:

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' 

そして、これはモデルの一部です:

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")) 

問題がありますか?フォームクリーンエラーが発生しない理由は何ですか?

答えて

2

model form is validatedの場合は、cleanメソッドを実行します。あなたが含まれていない完全なトレースバックを見ると、ビューがform.is_valid()を呼び出すときにエラーが発生し、フォームが保存されていないときにエラーが発生することがわかります。

モデルのクリーンメソッドでは、フォームのクリーンメソッドと同様にself.date_fromself.date_toが設定されていることを確認する必要があります。

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")) 

あなたは重複を防ぐために、フォームのcleanメソッドからチェックを削除することができます。

+0

ありがとうございました。 Date_fromとdate_toは必須のモデルフィールドなので、モデルを削除する前にチェックされているはずです。 –

関連する問題