user11665931
user11665931

Reputation:

Not a valid choice in Flask SelectField

After filling form I get that: 1

I was seeing a lot of ways to solve that problem here, in qaru, in reddit and I didn't find solving

So, this is my files:

webapp.py

from flask import Flask, render_template, send_file, make_response
from forms import AAForm
from create_plot import ploter
import os

app = Flask(__name__)

SECRET_KEY = os.urandom(32)
app.config['SECRET_KEY'] = SECRET_KEY

@app.route('/', methods=['GET', 'POST']) 
def index():
    form = AAForm()
    if form.validate_on_submit():
        bytes_obj = ploter(form.uniprot_ids.data, form.the_dye.data)
        return send_file(bytes_obj, 
                         attachment_filename='plot.png', 
                         mimetype='image/png')
    return render_template('index.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)

forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, SelectField, SubmitField
from wtforms.validators import DataRequired
from dyes_list import dyes

class AAForm(FlaskForm):
    uniprot_ids = StringField('Uniprot id', validators=[DataRequired()])
    the_dye = SelectField('Краситель', choices=dyes, validators=[DataRequired()])
    submit = SubmitField('Паехалиии!')

dyes_list.py

dyes = [
        (['K', 'R', 'H'], 'Кумасси бриллиантовый синий'),
        (['N', 'Q', 'C'], 'Окрашивание серебром'),
        (['K', 'R', 'H'], 'Амидо черный'),
        (['K', 'R', 'H'], 'Бромфеноловый синий'),
        (['K'], 'Пирогаллоловый красный'),
        (['K', 'R', 'H'], 'Sypro Ruby'),
        (['W'], 'Stain-free'),
        (['H', 'C', 'Q', 'N'], 'Zn-имидазольное негативное окрашивание'),
        ]

and index.html

<h1>Введите данные</h1>
    <form action="" method="post">
        {{ form.hidden_tag() }}
        <p>
            {{ form.uniprot_ids.label }}<br>
            {{ form.uniprot_ids(size=32) }}<br>
            {% for error in form.uniprot_ids.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>   
        <p>
            {{ form.the_dye.label }}<br>
            {{ form.the_dye(size=1) }}<br>
            {% for error in form.the_dye.errors %}
            <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </p>
        <p>{{ form.submit() }}</p>
        {% block content %}{% endblock %}
    </form>

P.s.: It's strange, but if you invert places keys and values in the "dyes" all will work good (at least you willn't get that problem).

Upvotes: 1

Views: 363

Answers (1)

pjcunningham
pjcunningham

Reputation: 8046

The values are sent back from the browser as strings which will not validate against an array of strings.

Instead have your values as CSV strings and then split into an array after the form has validated.

dyes = [
        ('K,R,H', 'Кумасси бриллиантовый синий'),
        ('N,Q,C', 'Окрашивание серебром'),
        ('K,R,H', 'Амидо черный'),
        ('K,R,H', 'Бромфеноловый синий'),
        ('K', 'Пирогаллоловый красный'),
        ('K,R,H', 'Sypro Ruby'),
        ('W', 'Stain-free'),
        ('H,C,Q,N', 'Zn-имидазольное негативное окрашивание'),
        ]

@app.route('/', methods=['GET', 'POST'])
def index():
    form = AAForm()
    if form.validate_on_submit():
        _dyes = form.the_dye.data.split(',')
        bytes_obj = ploter(form.uniprot_ids.data, _dyes)
        return send_file(bytes_obj,
                         attachment_filename='plot.png',
                         mimetype='image/png')
    return render_template('index.html', form=form)

Upvotes: 1

Related Questions