13

This is a question upon the use of wtforms SelectField.

Once the form submitted, I wish to extract selected text.

I have the following form:

from wtforms import Form, SelectField
class TestForm(Form):
     hour = SelectField(u'Hour', choices=[('1', '8am'), ('2', '10am') ])

Here's the view:

@app.route('/', methods=['GET', 'POST'])
def test_create():
form =TestForm(request.form)
if request.method == 'POST' and form.validate():
    test = Test()
    form.populate_obj(test)
    test.hour=form.hour.name
    db.session.add(test)
    db.session.commit()
    return redirect(url_for('test_create'))
return render_template('test/edit.html', form=form)

With test.hour=form.hour.name I obtain the attribute name (no surprise...), whilst I need the text (let's say 8am if the first option is chosen).

How should this be possible ? Thanks for any hint.

5 Answers 5

21

Define choices global in forms:

HOUR_CHOICES = [('1', '8am'), ('2', '10am')]

class TestForm(Form):
     hour = SelectField(u'Hour', choices=HOUR_CHOICES)

import it from forms, convert it to dict:

from .forms import HOUR_CHOICES

hour_display = dict(HOUR_CHOICES).get(form.hour.data)
Sign up to request clarification or add additional context in comments.

1 Comment

It doesn't work if the key is an integer! Weird
7

It was answered as a comment, so I'm writing here.

Use form.hour.data to get the value instead of the name.

Comments

4

If you don't need the choice indexes, is much more simpler:

class TestForm(Form):
  hour = SelectField(u'Hour', choices=[('8am', '8am'), ('10am', '10am') ])

1 Comment

Yes, but those choice indexes are almost never important. The indexes are implicit in a list.
3

When you set your choices, the list looks like [(index, value),...] so you don't need to import it, and probably shouldn't if setting dynamically

value = dict(form.hour.choices).get(form.hour.data)

Substitute self for form if inside form class

In general, I often zip the choices so index and value are the same. However, sometimes I want to present a displayed selection that's shorter than the value of interest. In that case, I think of it like [(value, display),...] and then the data variable is the value of interest. For example, [(abspath, basename), ...]

Comments

2

Another option is to get the index from form.hour.data and call it like this:

index = int(form.hour.data)
form.hour.choices[index][1]

1 Comment

More general solution would be to find the element itself: [c for c in form.hour.choices if c[0] == form.hour.data][0] and get the index then: c[1].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.