Why is my flask form validation returning Not a valid choice?

拈花ヽ惹草 提交于 2020-01-30 03:20:29

问题


I have been trying to figure out why my Flask form will not properly validate my select field choices even though the choices are coming from the select field options.

My assumption is that the select option when passed back from the server is unicode and is being compared to the choice which is a string, however, I thought coerce=str would fix that. I printed out the form data and request data which is the output below. Why isn't it working?

My code is attached below, removed csrf token key from the output dict. It seems like a very simple thing, but I can't figure it out.

forms.py

class PlatformForm(FlaskForm):
    platform_options = [('test', 'Test'), ('test2','Test2')]
    platforms = wtforms.SelectField('Platforms', choices=platform_options, coerce=str, validators=[DataRequired()])

views.py

@app.route('/', methods=['POST', 'GET'])
def index():
    form = forms.PlatformForm()
    if form.is_submitted():
        print form.data
        print request.form
    if form.errors:
        print form.errors
return render_template('home.html', form=form)

index.html

   {% extends "base.html" %}
   {% block content %}
   <h4>Select a Platform</h4>
   <form method="POST">
       {{ form.csrf_token }}
       <select class="custom-select" name="platform">
       {% for value, text in form.platforms.choices %}<br>
           <option value="{{ value }}">{{ text }}</option>
       {% endfor %}
       </select>
<button id="submit_inputs" type="submit" class="btn btn-default">Submit</button>
    </form>
    {% endblock %}

output

   {'platforms': 'None'}
   ImmutableMultiDict([('platform', u'test')])
   {'platforms': [u'Not a valid choice']}

EDIT: I figured out the problem. It's the way I'm creating the Select drop down through HTML and Jinja. Iterating through the choices and creating option tags doesn't seem to instantiate anything in the form data itself when passed back into Python. Changing that whole for loop to just

{{form.platforms}}

created a select drop down field that actually works.


回答1:


You have a name mismatch. In the form, you named your select field platforms (plural). In the HTML, you use platform (singular).

I recommend that instead of manually rendering the fields in your template, you let WTForms generate the HTML for you. For the form label, you can use {{ form.platforms.label }}, and for the actual field {{ form.platforms() }}. You can pass any attributes you want to field to have as keyword arguments.




回答2:


I think something might be going wrong because of the way you are rendering the form in your html file. If my hunch is right, try this:

{% extends "base.html" %}
{% block content %}
<h4>Select a Platform</h4>
<form method="POST">
    {{ form.hidden_tag() }}
    Select: {{ form.plaforms}}
    {{ form.submit(class="btn btn-default") }}
</form>
{% endblock %}

and then try if form.validate_on_submit() in your views.py file

taken from this stack overflow answer by pjcunningham:

"validate_on_submit() is a shortcut for is_submitted() and validate().

From the source code, line 89, is_submitted() returns True if the form submitted is an active request and the method is POST, PUT, PATCH, or DELETE.

Generally speaking, it is used when a route can accept both GET and POST methods and you want to validate only on a POST request."



来源:https://stackoverflow.com/questions/46271433/why-is-my-flask-form-validation-returning-not-a-valid-choice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!