redirect while passing arguments
You could pass the messages as explicit URL parameter (appropriately encoded), or store the messages into session
(cookie) variable before redirecting and then get the variable before rendering the template. For example:
from flask import session, url_for
def do_baz():
messages = json.dumps({"main":"Condition failed on page baz"})
session['messages'] = messages
return redirect(url_for('.do_foo', messages=messages))
@app.route('/foo')
def do_foo():
messages = request.args['messages'] # counterpart for url_for()
messages = session['messages'] # counterpart for session
return render_template("foo.html", messages=json.loads(messages))
(encoding the session variable might not be necessary, flask may be handling it for you, but can't recall the details)
Or you could probably just use Flask Message Flashing if you just need to show simple messages.
Flask - Redirect and passing arguments to the function
If all you want to do is serve the same template with the new language
setting, then it helps to know that home_page()
view is just a function. You can just call it:
@app.route('/lang=<language>')
def home_page_language(language):
return home_page(language)
Better still, you can register views under multiple routes, you don't actually need a second function here; just move the /lang=<language>
registration to the home_page()
function:
@app.route('/')
@app.route('/lang=<language>')
def home_page(language='en'):
return render_template(f"homepage - {language}.html")
Now /
will use 'en'
, and /lang=foobar
will call that same function with language='foobar'
.
If you were hoping to actually redirect the browser back to the /
URL (using a 30x Moved response), but at the same time keep the language setting, then you lose the information you stored in the URL path and have to record the language preference somewhere else. Most multilingual sites commonly store your language preference in a dedicated cookie, but you could also use the Flask session
object (which also is cookie based in the default setup).
To redirect to a different URL, use the flask.redirect()
function, then attach your cookie to the response object that that produces (using Response.set_cookie()
.
Your homepage will need to look for the language setting in the same cookie, it will not be part of the URL; I used a dedicated cookie here to store this information:
from flask import redirect, request, url_for
@app.route('/')
def home_page():
language = request.cookies.get('language', 'en')
return render_template(f"homepage - {language}.html")
@app.route('/lang=<language>')
def home_page_language(language):
redirected = redirect(url_for('home_page'))
redirected.set_cookie('language', language)
return redirected
If you were to store this information in the session object, you don't have to manually update the redirect response, the Flask framework handles that transparently for you:
from flask import session, redirect, url_for
@app.route('/')
def home_page():
language = session.get('language', 'en')
return render_template(f"homepage - {language}.html")
@app.route('/lang=<language>')
def home_page_language(language):
session['language'] = language
return redirect(url_for('home_page'))
How to pass arguments for return redirect(url()) in flask
When you provide keyword arguments to the url_for
function, Flask automatically encodes your values into URI components and appends them to your request url.
Using your code as an example, doing this
msg11='Saved Successfully'
return redirect(url_for('editProfile', msg11=msg11))
Will yield this URL when passed to the editProfile
route
/editProfile?msg11=Saved+Successfully
You can easily extract this value using Flask's built-in request
object
from flask import request
# Inside of editProfile() route
msg11 = request.args.get('msg11', None)
That way, you can simply check if this value exists (calling get()
is the same as the usual Python convention where a value of None
will be returned if the value is not found) and pass it along to your HTML template.
Furthermore, using Jinja's functionality you can display the message only if it is not a None
value by using something like this
{% if msg11 is not none %}
<h1>{{ msg11 }}</h1>
{% endif %}
A complete minimum example is outline below
app.py
from flask import Flask, render_template, redirect, url_for, request
app = Flask(__name__)
@app.route("/updateProfile", methods=["GET", "POST"])
def updateProfile():
msg11 = "Saved Successfully"
return redirect(url_for("editProfile", msg11=msg11))
@app.route("/editProfile")
def editProfile():
msg11 = request.args.get("msg11")
return render_template("editProfile.html", msg11=msg11)
if __name__ == "__main__":
app.run()
templates/editProfile.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>editProfile</title>
</head>
<body>
{% if msg11 is not none %}
<h1>{{ msg11 }}</h1>
{% else %}
<h1>msg11 has a value of None</h1>
{% endif %}
</body>
</html>
How can I pass arguments into redirect(url_for()) of Flask?
The redirect is fine, the problem is with the found
route. You have several ways to pass values to an endpoint: either as part of the path, in URL parameters (for GET requests), or request body (for POST requests).
In other words, your code should look as follows:
@app.route('/found/<email>/<listOfObjects>')
def found(email, listOfObjects):
return render_template("found.html",
keys=email, obj=listOfObjects)
Alternatively:
@app.route('/found')
def found():
return render_template("found.html",
keys=request.args.get('email'), obj=request.args.get('listOfObjects'))
Also, your redirection should provide request parameters, not template parameters:
return redirect(url_for('found', email=x, listOfObjects=y))
How to pass arguments to HTML form using flask in case of redirection
So here's what I tried, I made a global dictionary
and keep updating it wherever needed, now whenever I want to access some values I directly access it from my dictionary and render it using jinja
templating. Apart from this method there are other ways as well like storing data in flask.session
also one can use flask.flash()
to render messages and access them using messages.get()
function in their jinja template, but the problem with it is, it only provides a limited amount of size, if you pass an object or string of beyond that size, the browser simply ignores it and your messages will not be displayed because the message passed is in the form of browser-cookies
. So, storing them in my global dictionary works for me:
Here's a small snippet of my final code which similarizes the code I have posted as question:
# Globals
info = {
'logged_in' : False,
'user' : {},
'tasks' : [],
'status' : {
'value' : '',
'positive' : True
}
}
def reset():
'''
function to reset the values of info object
'''
global info
info['logged_in'] = False
info['user'] = {}
info['tasks'] = []
info['status'] = {
'value' : '',
'positive' : True
}
# Setting Up Route for Register Page
@app.route('/register/', methods=['GET', 'POST'])
def register():
'''
function to register an account into the server and database
'''
global info
# Fetching Form Data
user = {
"name": request.form.get('name'),
"email": request.form.get('email'),
"username": request.form.get('username'),
"password": request.form.get('password'),
"tasks":[]
}
# Inserting data to Database and Redirecting to Login Page after Successful Registration
if user['name'] != None:
user['password'] = pbkdf2_sha256.encrypt(user['password'])
if mongo.db.appname.find_one({"username": user["username"]}):
info['status']['value'] = 'Username Already Taken'
info['status']['positive'] = False
return redirect(url_for('register'))
else:
mongo.db.appname.insert(user)
info['status']['value'] = 'Registered Successfully'
info['status']['positive'] = True
return redirect(url_for('login'))
status_val = info['status']['value']
positive_status = info['status']['positive']
reset()
return render_template('register.html', value = status_val, positive = positive_status)
How to pass a variable in `redirect(url_for())`
In first_hop
, the parameters can be obtained using request.args.get('delay')
.
@app.route('/first_hop')
def first_hop():
x = request.args.get('delay')
print(x)
return redirect(url_for('second_hop'))
Related Topics
Generating Sublists Using Multiplication ( * ) Unexpected Behavior
Write Dictionary of Lists to a CSV File
Importerror: No Module Named 'Bottle' - Pycharm
How to Read the Contents of an Url with Python
How to Call Python Code from C Code
Check for Identical Rows in Different Numpy Arrays
How to Run Function in a Subprocess Without Threading or Writing a Separate File/Script
The Main() Function Appears to Not Work
How to Do N-D Distance and Nearest Neighbor Calculations on Numpy Arrays
In Python, How to Escape Newline Characters When Printing a String
Numpy: Fix Array with Rows of Different Lengths by Filling the Empty Elements with Zeros
Select Multiple Ranges of Columns in Pandas Dataframe
How to Import a Python Module from a Sibling Folder
How to Create an Object for a Django Model with a Many to Many Field
How to Redirect Stderr in Python
How to Replace Django's Primary Key with a Different Integer That Is Unique for That Table