0

EDITED. My original question wasn't clear enough. I want to allow a user to pass values into a TextField in wtforms, then the value they entered appears after they add it. This would allow the user to pass multiple values before then hitting a final "Sumbit" button on all the values that were originally entered.

I found this question for doing something with the entered text, which is what I tried.

My Python code:

from flask import Flask, request, render_template, redirect
from wtforms import TextField, Form, SubmitField


def redirect_url(default='index'):
    return request.args.get('next') or \
           request.referrer or \
           url_for(default)


class RegionForm(Form):
    field = TextField('Region')
    Submit = SubmitField('AddRegion')
    fieldList = []


def main():
    app = Flask(__name__)

    @app.route('/region/', methods=['GET'])
    def region():
        form = RegionForm(request.form)

        return render_template("region.html",
                               form=form)


    @app.route('/add/', methods=['POST'])
    def add():
        request.form['fieldList'].append(request.form['field'])
        return redirect(redirect_url())

    app.run(debug=True)

My html code:

<form action="/add/" method="Post">
{% for field in form %}
    <tr>
        <th>{{ field.label }}</th>
        <td>{{ field }}</td>
    </tr>
{% endfor %}
</form>
{% for item in form.fieldList %}
    {{ item }}
{% endfor %}

But after I enter the text and click the "AddRegion" button, I get the following error: The browser (or proxy) sent a request that this server could not understand. However, if I comment out the line request.form['fieldList'].append(request.form['field']), then the redirect happens, but the text hasn't been added to the hidden list on the form. How do I both add the text to the list and redirect back to the original page, so the user can add more text? It seems like there must be an error with this line only, because the rest works fine.

How can I allow a user to dynamically add text to a field, then have that field display in the browser? Then once the complete region fields have been added, I want to be able to retrieve that list to process in a separate function later.

Community
  • 1
  • 1
unasalusvictis
  • 145
  • 1
  • 1
  • 6

2 Answers2

0

Part One

So after looking at your code, I think I have found your problem. Flask is very particular about its app routes.

The app route that you have in your flask is:

@app.route('/add', methods=['POST'])

However, your current action on your form which is: <form action="/add/" method="Post">

In flask /add and /add/ are actually two different web-routes. Therefore, the @app.route is not being triggered. If you change your code to:

`<form action="/add" method="post">`

You should be good to go from here.

Part Two

I think I may have an additional issue. So within your HTML right now, you actually close your </form> tag before looping through your items in the fieldList.

</form> {% for item in form.fieldList %} {{ item }} {% endfor %}

Try:

{% for item in form.fieldList %} {{ item }} {% endfor %} </form>

What I believe to be happening is that your form inputs are not actually being placed inside of the form so when you try to access them you are getting a KeyError.

Cody Myers
  • 191
  • 5
  • Good catch, but I'm still getting the same error. If I comment out the line with `request.form['fieldList']...`, then it runs fine, but doesn't add the input to the hidden list in the form like I want it to. – unasalusvictis Feb 03 '17 at 16:58
0

I second what Cody Myers said. However there's a simple way to guarantee correct routes even if you later change them: in your form use action="{{ url_for('region') }}" and Flask will automatically substitute the correct route for the given function name.

Hugo
  • 582
  • 4
  • 10