M.Izzat
M.Izzat

Reputation: 1166

django - Form ValidationError not working

I'm trying to raise Validation error where :

1) if the date selected in the start_date field is the day before today then it will raise and error. when I submit it throw this error

'<' not supported between instances of 'NoneType' and 'datetime.date'

2) if end date is a date before the start date, it will raise another error. For this part its partially work where I doesn't save the submitted form but it doesn't raise and validation error

I know this is not the first time somebody ask this question but I followed the answer given by others and it's not working, where I do wrong?

Any help is much appreciate.

Below is my code :

model.py:

class Leave(models.Model):
    employee = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='+')
    start_date = models.DateField()
    end_date = models.DateField()
    duration = models.FloatField()

form.py :

class LeavesDetailForm(forms.ModelForm):

    class Meta:
        model = Leave
        fields = ('employee', 'type', 'status', 'start_date', 'end_date', 'duration', 'comment')
        widgets = {'start_date': forms.DateInput(attrs={'type': 'date'}),
                   'end_date': forms.DateInput(attrs={'type': 'date'}),
                   'employee': forms.HiddenInput(),
                   'duration': forms.HiddenInput(),
                   'status': forms.HiddenInput()}

    def clean(self):
        start_date = self.cleaned_data.get("start_date")
        end_date = self.cleaned_data.get("end_date")
        if end_date < start_date:
        msg = u"End date should be greater than start date."
        self._errors["end_date"] = self.error_class([msg])
        raise forms.ValidationError("End date should be greater than start date.!")

    def clean_start_date(self):
        start_date = self.cleaned_data.get('start_date')
        if self.instance.start_date < datetime.date.today():
            raise forms.ValidationError("The date cannot be in the past!")
        return start_date

view.py :

def my_leaves_view(request):
    form = LeavesDetailForm(request.POST or None)
    leaves_log = Leave.objects.all().filter(employee=request.user.profile.employee.id)
        if form.is_valid():
        inst = form.save(commit=False)
        inst.start_date = form.cleaned_data['start_date']
        inst.end_date = form.cleaned_data['end_date']
        duration = (inst.end_date - inst.start_date).days
        inst.duration = duration
        inst.save()
        return HttpResponseRedirect('my_leaves_content.html')
    context = {'form': form}
    return render(request, 'hrm/my_leaves/my_leaves_content.html', context)

Upvotes: 0

Views: 1353

Answers (2)

Alasdair
Alasdair

Reputation: 309089

In the clean method, start_date or end_date may be None if the user did not submit a valid date.

As the error suggests, Python won't let you compare a date instance with None.

You should check that you got valid dates from cleaned_data before you compare them:

if end_date is not None and start_date is not None and end_date < start_date:

In the clean_start_date method, you should use start_date which you fetched from cleaned_data, not self.instance.start_date:

def clean_start_date(self):
    start_date = self.cleaned_data.get('start_date')
    if start_date < datetime.date.today():
        raise forms.ValidationError("The date cannot be in the past!")
    return start_date

Upvotes: 0

Jahongir Rahmonov
Jahongir Rahmonov

Reputation: 13753

Looks like you just named the function wrong. Change clean_date to clean_start_date as it should be in the format clean_function_name.

Hope it helps!

Upvotes: 0

Related Questions