1

I am new to flask an am having an issue with creating a dynamic url from form data. Specifically from the value of a SelectField of WTFORMS. My code is as follows

My form looks like this

from flask_wtf import Form
from wtforms import SelectField
from wtforms.fields.html5 import DateField


class SelectEventForm(Form):
    sports = SelectField(u'Select Sport')
    start_after_date = DateField('Starts After Date')
    start_before_date = DateField('Starts Before Date')

My controller has the following code

@app.route('/event', methods=['GET', 'POST'])
def event():
    form = SelectEventForm(request.form)
    sports = betfair_client.call_rest_api('listEventTypes/', {"filter": {}})
    form.sports.choices = []
    for sport in sports:
       for key in sport:
           form.sports.choices.append((key, sport[key]))
   return render_template('events.html', form=form)


@app.route('/event/<sports>', methods=['GET', 'POST'])
def event_select(sports):
    #print request.form
    #print request.form.get('sports')
    return render_template('events_two.html')

The form in html is as follows

<form  class="form-style-7" action="{{ url_for('event_select',     sports=form.sports.sport) }}" method="post">
  <ul>
    <li name="sport">
      {{ form.sports.label}} {{ form.sports }}
    </li>

    <li>
      {{ form.start_after_date.label }} {{ form.start_after_date }}
    </li>
    <li>
      {{ form.start_before_date.label }} {{ form.start_before_date }}
    </li>

    &nbsp;
    &nbsp;
   <li>
    <input type="submit" value="Next">
   </li>
</ul>
</form>

What I would like to do, is se the value from the SelectField to generate the url. Have been stuck on this for some time. The form itself and the drop down list display everything correctly

Thanks

1 Answer 1

2

I'd change your form to post back to it's generating page, and then deal with the logic from there. So change

{{ url_for('event_select', sports=form.sports.sport) }}

to just:

{{ url_for('event') }}

then adjust your event method to be something like:

from flask import redirect

@app.route('/event', methods=['GET', 'POST'])
def event():
    form = SelectEventForm(request.form)

    if form.validate_on_submit():
        chosen_sport = form.sports.data
        return redirect(url_for('event_select', sports=chosen_sport))

    sports = betfair_client.call_rest_api('listEventTypes/', {"filter": {}})
    form.sports.choices = []
    for sport in sports:
       for key in sport:
           form.sports.choices.append((key, sport[key]))
   return render_template('events.html', form=form)

All we're doing is grabbing the from if it's submitted, then grabbing the chosen sport from the form element, and then using that to redirect the user to the event_select method with the chosen sport as the argument.

Sign up to request clarification or add additional context in comments.

2 Comments

Nice explanation thanks. I had thought of introducing a go between function as a work around but thought there must be a better way so this looks good. Can you explain why we pass request.form to instantiate the form object? This confused me to begin with. Thanks
Actually, you don't need to supply it at all if you're using Flask-WTF, because it grabs the request.form automatically. The reason why, is when you create your form (form = ExampleForm()) it's empty (e.g. form.sports.data would be empty) so you want WTF to translate your http form to your python form object and you do that by supplying the request.form object to it, so it knows where to look to find any data it needs to fill itself.

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.