2017-11-27 5 views
0

전체 양식 유효성 검사를 받기 전에 내 모델 clean이 호출되는 이유는 무엇입니까?Django : 양식 정리 전에 호출 된 모델 정리 메서드

내 양식에 필수 입력란이 있습니다. 만약 내가 그것들을 채우지 않으면, 나는 형식 오류를 얻지 않고, 대신 model clean 메서드가 호출된다. (save가 호출 되었기 때문에 그렇다고 가정한다.) 내가 date_to 필드가 작성되지 않았기 때문에

if self.date_from > self.date_to 

이 NoneType

에 datetime.date을 비교할 수 없습니다 :

그것은 모델 clean() 방법을 충돌합니다. 양식이 그것을 처리해야한다고 생각하고 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는 필수 모델 필드이므로 모델을 정리하기 전에 체크하고 있다고 가정합니다. –