wtforms: InputRequired doesn't accept 0 as valid

Hello,

I have a form that looks like this,

class VoteForm(Form):
    article_id = IntegerField('article_id', [validators.DataRequired()])
    vote_type  = IntegerField('vote_type', [validators.InputRequired(), validators.NumberRange(min = 0, max = 1)])

and create the form with,

form = VoteForm(data = request.json_body)

request.json_body is the dictionary {u'article_id': 1, u'vote_type': 0}.

I would expect that the value 0 is fine with InputRequired but it seems it is not.

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Reactions: 1
  • Comments: 15 (1 by maintainers)

Commits related to this issue

Most upvoted comments

I believe this issue should be reopened. It is not at all intuitive that InputRequired validator should fail on BooleanField when the value is False, since InputRequired specifically tests for whether a value is specified rather than truthiness. This is especially annoying when building APIs.

Yes, there is a workaround. Nevertheless, InputRequired is broken according to its own spec. At the very least the documentation should reflect this fact. However, the change should just be merged into mainline.

To address backwards compatibility, just bump the major version to indicate a breaking change.

Why this issue was closed and how to handle it? I have

class MyForm(wtforms.Form):
    hour = wtforms.IntegerField(validators=[validators.InputRequired(), validators.NumberRange(0, 23)])

and when I pass 0 as hour validation fails… Input is present so I don’t expect InputRequired() to complain.

why close this issue? the problem is still exist, i have to change the field‘s attribute to OPtional() to avoid the error …

Hi @wilbertom, I’ve read your diff, but what bothers me, why it’s not in the core. Is this solution bad?

My workaround is to replace the InputRequired validator with a AnyOf([True, False]).

Also, neither InputRequired nor DataRequired accept False as a valid input for a BooleanField.

    def test_required_bool(self):
        class TestForm(wtforms.Form):
            required_bool = wtforms.BooleanField(validators=[wtforms.validators.InputRequired()])

        form = TestForm()
        self.assertFalse(form.validate(), form.errors)
        self.assertTrue('required_bool' in form.errors)

        form.process(required_bool=False)
        self.assertEqual(form.required_bool.data, False)
        self.assertTrue(form.validate(), form.errors) # Fails with form.errors containing {'required_bool': [u'This field is required.']}

This means that when a BooleanField is required, it is required to be True!