Tuffail
Tuffail

Reputation: 87

WTForms - Create form with both or no fields that validates but not just one field

I want this form to validate if there is a date attribute in both inputs or there's no date input at all, but not when only either one input is entered.

So if you have a start date you must have an end date, and vice versa but you can't just put a start or end date alone.

My code is as below:

class MyForm(Form):
start = DateTimeField(u'Start', format='%Y-%m-%d')
end_date = DateTimeField(u'End', format='%Y-%m-%d')

So, it validates if, either:

Shouldn't validate if:

Thanks in advance for your help!

Upvotes: 1

Views: 1074

Answers (2)

Tuffail
Tuffail

Reputation: 87

I ended up solving it like this:

Created a function called validator outside the class definition:

def validator(form, field):
    a = self.start.field.data
    b = self.end_date.field.data
    if not ((a and b) or not (a or b)):
        raise ValidationError('Both or none dates must exist.')

And modified the class like this:

class MyForm(Form):
    start = DateTimeField(u'Start', [validators.Optional(), validator], format='%Y-%m-%d')
    date_end = DateTimeField(u'End', [validators.Optional(), validator], format='%Y-%m-%d')

Needed to add optional validator since WTForm by default makes DateTimeField a required field

Upvotes: 0

jensmtg
jensmtg

Reputation: 506

If you're not interested in using the constraint in other forms, you could override the validate function in-line. More: http://wtforms.readthedocs.io/en/latest/validators.html#custom-validators

class MyForm(Form):
    start = DateTimeField(u'Start', format='%Y-%m-%d')
    end_date = DateTimeField(u'End', format='%Y-%m-%d')

    def validate(self):
        if not Form.validate(self):
            return False

        a = self.start.field.data
        b = self.end_date.field.data
        if (a and b) or not (a or b):
            return True
        else:
            self.start.field.errors.append('Both or none dates must exist.')
            return False

Upvotes: 1

Related Questions