Yurrili
Yurrili

Reputation: 338

Raising ValidationError when it comes to custom validation

i have problem with showing an error in form.

Let say, that my form has 2 fields, which are not require only if they are both empty, but we cannot let to situation when only one has a value. So i tried to do this validation in view and then raise an exception, and everything is okay, BUT Error is raised as debug page with traceback etc.

raise utils.ValidationError(u'SOME EXAMPLE TEXT')

This was in view.

So I tried other way, i've readed that i can do validation in def clean in form

IN FORM

def clean(self):
    super(forms.Form,self).clean()
    if 'departure_date_time_plain' in self.cleaned_data and 'arrival_date_time_plain' not in self.cleaned_data:
        self._errors['arrival_date_time_plain'] = [u'PUT HERE SOME DATE']

    if 'departure_date_time_plain' not in self.cleaned_data and 'arrival_date_time_plain' in self.cleaned_data:
        self._errors['arrival_date_time_plain'] = [u'PUT HERE SOME DATE']
    return self.cleaned_data

VIEW My view code for second approach:

def new_bus(request, id, id_sec):
    args = {}
    args.update(csrf(request))
    if request.method == 'POST':
        train_form = TrainForm(request.POST)
        args['new_train'] = train_form
        if "train" in request.POST and train_form.is_valid():
            if train_form['reservation_train'].value():
                 train = Train.objects.create(                  
                    transportation=train_form['trans'].value(),
                    number=train_form['num'].value(),                                    
                    departure=train_form['departure_date_time_train'].value(),
                    arrival=train_form['arrival_date_time_train'].value(),
                    reservation=train_form['reservation_train'].value(),
                    seat_number=train_form['seat_number_train'].value(),
                    section_numbers=train_form['section_numbers_train'].value()
                    )
            else:
                 train = Train.objects.create(reservation=False)

           sec = Section.objects.get(id=id_sec)
           sec.locomotion = JourneyType.objects.create(train=train)
           sec.save()
           return HttpResponseRedirect('/trip/'+ id)
    args['new_train'] = TrainForm()
    return render(request, 'add_trip/new_bus.html', args)

And this method don't ever were called, could you tell my how to resolve this problem ? Because i run out of tutorials, and any other options, or maybe i just missed something. I would be grateful for any answer

-- ANSWER --

Thanks for comments from @Shang Wang i found out what was really a problem. Clean is going to call only when your field is requierd=True, and my errors wasn't correctly showing because of one mistake:

Instead of :

bus_form = BusForm(request.POST)
plain_form = PlainForm(request.POST)
train_form = TrainForm(request.POST)
args['new_bus'] = bus_form
args['new_plain'] = plain_form
args['new_train'] = train_form

I had:

bus_form = BusForm()
plain_form = PlainForm()
train_form = TrainForm()
args['new_bus'] = bus_form
args['new_plain'] = plain_form
args['new_train'] = train_form

Upvotes: 1

Views: 573

Answers (1)

Shang Wang
Shang Wang

Reputation: 25539

I think your problem for your second approach is that you didn't captured the cleaned_data that is returned from parent clean method. Also you were calling the wrong super method. super should be called on the form class itself, not the class that current class is inherited from. I think you should:

class CurrentForm(forms.Form):

    def clean(self):
        cleaned_data = super(CurrentForm, self).clean()
        if 'departure_date_time_plain' in cleaned_data and 'arrival_date_time_plain' not in cleaned_data:
            self._errors['arrival_date_time_plain'] = [u'PUT HERE SOME DATE']

        if 'departure_date_time_plain' not in cleaned_data and 'arrival_date_time_plain' in cleaned_data:
            self._errors['arrival_date_time_plain'] = [u'PUT HERE SOME DATE']
        return self.cleaned_data

You will always have the best tutorial by checking out django docs.

Upvotes: 2

Related Questions