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

I have a very simple question regarding URL changes. Suppose I have an HTML page http://example.com/create that encodes a form with some input fields. From these input fields, I want to create a python list that should be used to create another HTML page http://example.com/show_list containing a list based on the values ​​of the python list.

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

 @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 the problem! return render_template( "create.html") 

Suppose parse_form_data_and_return_list(...) accepts user input and returns a list with some string values. I added a comment to the line that bothers me. I will return to it in a second, but first I will give you a page template ( http://example.com/show_list ), which should be loaded AFTER user input:

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

It basically works great. The list values ​​are "passed" to the Jinja template, and the list is displayed.

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

So I thought about creating my own route for show_list and in the create() method that calls redirect , instead of directly converting the next template. Like this:

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

But in this case, I do not see how to pass the list object to show_list() . Of course, I could parse each element of the list into a URL (from here send it to http://example.com/show_list ), but this is not what I want to do.

As you may have already learned, I'm pretty new to web development. I guess I just use the wrong template or did not find a simple API function that does the trick. Therefore, I ask you to show me a way to solve my problem (briefly in the summer): draw a show_list template and change the URL from http://example.com/create to http://example.com/show_list using the list created in the method create() / route.

+4
source share
2 answers

If the list is not very long, you can pass it to the query string, for example, a comma:

 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 this:

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

For longer lists, or if you do not want to expose them in the query string, you can also save the list in 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 %} 
+7
source

Besides saving the list in a session, you can also just change your form action for publishing to a new route. Then process the form data from the show_list route and draw your template.

Form Header:

 <form action="{{ url_for('show_list') }}" method="post"> 

Updated show_list route:

 @app.route('/show_list', methods=['GET', 'POST']) def show_list(): if request.method == 'POST': some_list = parse_form_data_and_return_list(...) return render_template("show_list.html") else: # another way to show your list or disable GET return render_template("show_list.html") 

I'm not necessarily against using session storage, but I think it’s cleaner not to use it, since you don’t have to worry about releasing session variables.

0
source

Source: https://habr.com/ru/post/1496765/


All Articles