Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I "redirect" to another URL and pass a list object using Flask

Tags:

python

flask

I have a very basic question regarding URL changes. Let's assume I have a HTML page http://example.com/create that conatins a form with some input fields. From this input fields I want to create a python list which should be used to generate another HTML page http://example.com/show_list containing a list based on the python's list values.

So the view for http://example.com/create is:

@app.route('/create', methods=['GET', 'POST']) 
def create():

if request.method == 'POST':
    some_list = parse_form_data_and_return_list(...)
    return render_template( "show_list.html", some_list=some_list)  #here's the problem!

return render_template( "create.html")

Assume that parse_form_data_and_return_list(...) takes the user input and returns a list with some string values. I added a comment to the line that troubles me. I'll come back to it in a second but first give you the template of the page (http://example.com/show_list) that should be loaded AFTER the user input:

{% block content %}
<ul class="list">       
  {% for item in some_list %}
    <li>
        {{ item }}
    </li>
  {% endfor %}
</ul>
{% endblock content %}

Basically this works fine. The list values are "passed" to the Jinja template and the list is shown.

If you now again have a look to my route method you can see that I am only doing render_template to show the shwo_list page. For me this has one disadvantage. The URL will not be changed to http://example.com/show_list, but will stay at http://example.com/create.

So I thought about creating a own route for show_list and in the create() method calling redirect instead of rendering the next template directly. Like this:

@app.route('/show_list')
def tasklist_foo():
return render_template( "show_list.html" )

But in this case I don't see how I could pass the list object to show_list(). I could of course parse every single item of the list to the URL (hence post it to http://example.com/show_list), but that's not what I want to do.

As you already might have recognized, I'm pretty new to web developing. I guess I just use a wrong pattern or haven't found a simple API function that does the trick. So I kindly ask you to show me a way to solve my problem (shortly summerized): render the show_list template and change the URL from http://example.com/create to http://example.com/show_list using the list created in the create() method/route.

like image 491
cyphorious Avatar asked Aug 13 '13 10:08

cyphorious


1 Answers

If the list isnt very long, you could pass it on the query string, say comma separated:

comma_separated = ','.join(some_list)
return redirect(url_for('show_list', some_list=comma_separated))
# returns something like 'http://localhost/show_list?some_list=a,b,c,d'

Then in the template in your view, you can iterate over them like so:

{% for item in request.args.get('some_list', '').split(',') %}
    {{ item }}
{% endfor %}

For longer lists, or if you didnt want to expose it on the query string, you could also store the list in the session:

session['my_list'] = some_list
return redirect(url_for('show_list'))

Then in the template:

{% for item in session.pop('my_list', []) %}
    {{ item }}
{% endfor %}
like image 119
DazWorrall Avatar answered Sep 19 '22 22:09

DazWorrall