-
-
Notifications
You must be signed in to change notification settings - Fork 397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Validation failure in SelectField #804
Comments
Hi. Can you describe your usecase? |
Hello, See my code example: from wtforms import Form, SelectField, validators
class MyForm(Form):
def render_visitor_timer_choices():
choices = [
(1, 'One'),
(2, 'Two'),
(3, 'Three'),
(4, 'Four')
]
return choices
visitor_timer = SelectField(
label='Time in seconds',
validators=[
validators.Optional(),
validators.NumberRange(
min=1,
max=4
)
],
choices=render_visitor_timer_choices,
coerce=int,
validate_choice=True,
render_kw={
'data-required': 'true'
}
)
form = MyForm(data={'visitor_timer': 5})
print(form.visitor_timer.choices) # Result: [(1, 'One'), (2, 'Two'), (3, 'Three'), (4, 'Four')]
print(form.validate()) # Result: True
print(form.visitor_timer.data) # Result: 5
"""
The response from *form.validate()* is True for the value 5 which is not in the SelectField's choices.
Shouldn't *form.validate()* be False?
""" |
Sharing my investigation: the minimal form I could write to reproduce this is: >>> from wtforms import Form, SelectField, validators
... from werkzeug.datastructures import ImmutableMultiDictMixin
...
... class MyForm(Form):
... visitor_timer = SelectField(
... validators=[validators.Optional()],
... choices=[('1', 'One')],
... )
...
... form = MyForm(data={'visitor_timer': '5'})
... print(form.validate())
True The validation result is >>> from wtforms import Form, SelectField, validators
...
... class MyForm(Form):
... visitor_timer = SelectField(
... choices=[('1', 'One')],
... )
...
... form = MyForm(data={'visitor_timer': '5'})
... print(form.validate())
False Or if >>> from wtforms import Form, SelectField, validators
... from werkzeug.datastructures import ImmutableMultiDict
...
... class MyForm(Form):
... visitor_timer = SelectField(
... validators=[validators.Optional()],
... choices=[('1', 'One')],
... )
...
... form = MyForm(ImmutableMultiDict({'visitor_timer': '5'}))
... print(form.validate())
False I think what is going on is: when the form is initialized with What is your real-world usecase? Do you really use form validation without passing form data, or was it just there to fill the bug report? |
Hello, I use data= instead of formdata= because I'm using wtforms to validate data received through my api created with Flask-Restfull. Then I receive the request data through: data = request.get_json()
form = MyForm(data=data) And I do validation and so on... Based on your answer, my question now is: form = MyForm(ImmutableMultiDict(data)) will this work correctly? |
@HK-Mattew For your example form this will work but it will not work for all the possible field types since But I also don't really understand your use-case, how are you generating the JSON payload? Or is your goal to provide both a generic API interface and a renderable form from a single form definition and get shared validation regardless of input method? Something like pydantic should be better suited towards generic input validation. Generating a |
Hi @Daverball , I'm generating the raunchy JSON payload from javascript. In this case I create the object. I already use Pydantic models, but I didn't think about putting them in the foreground to validate the data. But it's a good option you gave me. |
@HK-Mattew In that case couldn't you just submit the raw formdata, rather than try to create a JSON payload? It seems like a lot of work to juggle around the backend data representation in the frontend if ultimately you just want to validate the form input. |
@Daverball I can't send the raw data. Because I use the API to submit form data from my website and also to use the API externally (outside the browser). |
Even when inserting a value that is not in choices= of the SelectField, the validation error is not issued. (Even though validate_choice=True is set).
The error is in this line of code: Code Line
The else: is not being triggered and does not generate the validation error it should.
Environment
The text was updated successfully, but these errors were encountered: