I am trying to get some phrase from the user, and when he/she will press "submit" i want to redirect him/her to another page with his/her name, using Flask. Here is my Python code:
from flask import Flask, redirect, render_template, request, session, url_for
app = Flask(__name__)
#app.route("/", methods = ["POST", "GET"])
def login():
if request.method == "POST":
user = request.form["name"]
return redirect(url_for("success", name=user))
else:
return render_template("login.html")
#app.route("/success", methods = ["POST", "GET"])
def success():
user = request.form.get('name')
return render_template("success.html", name=user)
if __name__ == "__main__":
app.run("0.0.0.0", 8080)
So when i go to my site i am going to "else" branch and do: "render_template("login.html")". Then if i press submit i go into "if" where i am trying to redirect the user to "success.html". Here is my login.html:
<html>
<body>
<form action = "http://ide50-zahar-zagrava.cs50.io:8080/" method = "post">
<p>Enter Name:</p>
<p><input type = "text" name = "name" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
And succes.html:
<html>
<body>
<h1>Hello {{ name }}!</h1>
</body>
</html>
But insted of saying: "Hello " it says: "Hello None".
My main question is how to pass data from one page to another?
I am completely new at Flask and Python, so i can't figure out what's going wrong.
your action from form is wrong.you are sending the form to the index page. you could edit it like:
<form action="{{ url_for('success') }}" method="post">
this way, your form will be sent to the success method.
Related
I am trying to build a simple Flask app in Python with two radio buttons and a "refresh" button, where, on clicking on the refresh button, the page reloads and displays the radio button selection on the previous page.
Routes.py:
#app.route("/")
def display():
return render_template("index.html", choice=choice)
if request.form['submit'] == 'Refresh':
choice= request.form.get("Choice")
return redirect(url_for('/'))
index.html:
<html>
<head>
<title>Choice</title>
</head>
<body>
<h2>Choice</h2>
<hr>
{{choice}}<br>
<form action="">
<input type="radio" name="Choice" value="Choice1"><span>Choice 1/span><br/>
<input type="radio" name="Choice" value="Choice2"><span>Choice 2</span>
<input type="submit" name="refresh" value="Refresh">
</form><br>
</form> </body>
</html>
Apply the below changes and check if it works!
render_template, request, redirect, url_for was used but not imported. Try to import them.
from flask import Flask, render_template, request, redirect, url_for
To retrieve POST data, you can use request.form.
To retrieve GET data, you can use request.args.
Try the below code if you want to use request.args:
#app.route("/")
def display():
choice = request.args.get('Choice','None Selected')
return render_template("index.html", choice=choice)
if request.args.get('refresh') == 'Refresh':
return redirect(url_for('display',Choice=choice))
Try the below code if you want to use request.form:
#app.route("/",methods = ['POST', 'GET'])
def display():
if request.method == 'GET':
choice = request.args.get('Choice','None Selected')
return render_template("index.html", choice=choice)
if request.method == 'POST':
choice= request.form.get("Choice")
return redirect(url_for('display',Choice=choice))
In index.html add <form action="" method="POST"> to send the form data
I'm new to Flask. This is the content of my login.html file:
<html>
<body>
<form action="localhost:5000/login" method="POST">
<p>Enter name : </p>
<p><input type = "text" name="nm"/></p>
<p><input type = "submit" value="submit"/></p>
</form>
</body>
</html>
This is app.py file:
from flask import Flask, redirect, url_for, request
app = Flask(__name__)
#app.route('/success/<name>')
def success(name):
return "Welcome %s" % name
#app.route('/login', methods = ['POST', 'GET'])
def login():
if request.method == 'POST' :
user = request.form['nm']
return redirect(url_for('success', name = user))
else :
user = request.args.get('nm')
return redirect(url_for('success', name = user))
if __name__ == "__main__":
app.run(debug = True)
When I entered a text in my HTML login form and click the submit it should have redirected to the desired URL but nothing happened.
Edit
After trying with changes suggested by Rogan Josh, i got this error:
File not found
Firefox can’t find the file at /home/hp/flask_practice/{{ url_for('login') }}.
Check the file name for capitalization or other typing errors.
Check to see if the file was moved, renamed or deleted.
Your code can't do anything because you haven't actually served the html from your flask application. You've just double-clicked it and opened the HTML in a browser.
Your html file needs to go in a subdirectory from app.py called "templates". Then change your code to:
from flask import Flask, redirect, url_for, request, render_template
app = Flask(__name__)
#app.route('/success/<name>')
def success(name):
return "Welcome %s" % name
#app.route('/login', methods = ['POST', 'GET'])
def login():
if request.method == 'POST' :
user = request.form['nm']
return redirect(url_for('success', name = user))
else :
user = request.args.get('nm') # THIS DOES NOTHING
return render_template('login.html') # CHANGED HERE
if __name__ == "__main__":
app.run(debug = True)
You should also update your HTML to:
<html>
<body>
<form action="{{ url_for('login') }}" method="POST">
<p>Enter name : </p>
<p><input type = "text" name="nm"/></p>
<p><input type = "submit" value="submit"/></p>
</form>
</body>
</html>
Now open the browser and go to 127.0.0.1:5000/login
Simply I am just trying to redirect to an url by using the below code in my login.html template:
<form>
<form action="/sessions">
<p>Username:</p>
<p><input type="text" minlength="8" name="username"required /></p>
<p>Password:</p>
<p><input type="text" name="password"/></p>
<input type="submit" value="Submit">
</form>
and
def login():
print("inside login")
return render_template('login.html')
#app.route("/sessions", methods=["GET","POST"])
def sessions():
userid = request.form.get("userid")
password = request.form.get("password")
return request.form.get("userid"), request.form.get("password")
but is stuck on the login() url. Also I tried
<form action="{{ url_for('sessions') }}">
but is not working as well. Not sure what I am missing? Please any hints/ideas would be highly appreciated.
Try this ( i just added one more line, the commented one):
#app.route("/sessions", methods=["GET","POST"])
def sessions():
userid = request.form.get("userid")
password = request.form.get("password")
if request.method == 'POST': #additional line
return request.form.get("userid"), request.form.get("password")
Updated answer reflects new comments
Found couple issues in your code:
HTML form is incorrect, you are using form in form
<form>
<form action="/sessions">
<p>Username:</p>
<p><input type="text" minlength="8" name="username"required /></p>
<p>Password:</p>
<p><input type="text" name="password"/></p>
<input type="submit" value="Submit">
</form>
You should change it to this
<html>
<body>
<h1>This is login page</h1>
<form action="{{ url_for('login') }}" method="POST">
<p>Username:</p>
<p><input type="text" minlength="8" name="username"required /></p>
<p>Password:</p>
<p><input type="text" name="password"/></p>
<input type="submit" value="Submit">
</form>
</body>
</html>
Notice changes, first there is only 1 form tag, then I use jinja2 engine to call the login in form.action, 2nd this login page handles serving login HTML when there is a GET request (initially opening this page) and for accepting form POST request with credentials.
Then I changed the routes to this:
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
#app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
user_name = request.form['username']
password = request.form['password']
print(user_name, password) # do something here?
return redirect(url_for('session'))
return render_template('login.html')
#app.route('/session')
def session():
return render_template('session.html')
Notice that now login accepts both methods, GET and POST, as mentioned before, GET is for serving HTML content and POST is for submitting form data. In the login endpoint I have a condition that checks, if it's a POST method request, then I extract credential details from request.form and after doing something (e.g. in that print() statementIreturn redirect(url_for('session'))`.
This is how you manage redirects from one page to another by clicking submit on one of a pages.
original answer that was incorrect
In Flask to redirect, you could you something like this:
from flask import url_for, redirect
#app.route('/sessions', methods['GET', 'POST']
def sessions():
# some code
return redirect(url_for('some.endpoint'))
This will redirect you to a specific endpoint that you will provide. In the docs there is more info about it.
Problem transferring variables across views I tried using sessions and could not get the connection to work. Say I have two pages, a home and page2. I have a flask app that will take user input from the home and print out input on page2.
For example, if you start my app, you will see this as the home page:
This part works fine, I am able to enter a value.
What I want to happen next, is after you click submit, page2 is generated showing what was just entered:
Whatever string value was entered on home should show up in the highlighted portion.
I have the following app.py file:
from flask import Flask, render_template, request, session
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def home():
stringval = ''
if request.method == 'POST' and 'stringval' in request.form:
stringval = request.form.get('stringval')
session["stringvalue_topass"] = stringval
return render_template('page2.html', stringval = stringval)
return render_template("home.html")
#app.route('/page2', methods=['GET', 'POST'])
def page2():
stringvalue_get = session.get('stringvalue_topass')
return render_template('page2.html', stringvalue_get = stringvalue_get)
if __name__ == '__main__':
app.run(debug=True)
The following home.html:
<!doctype html>
<h1>Enter Value </h1>
<div class="main">
<form class="pure-form" method="POST" action="/page2">
stringval:<br>
<input type="text" name="stringval"><br>
<button type="submit" class="pure-button pure-button-primary" value="Submit">Submit!</button>
</form>
</div>
</body>
And the following page2.html
<!doctype html>
<h1>You have selected </h1>
<div class="main">
{% if stringvalue_get %}
<pre>
{% print(stringvalue_get) %}
</pre>
{% endif %}
</div>
</body>
Okay, there are a few issues here. Firstly, the action attribute of your form in home.html is set to "/page2". This means that when the form is submitted, the POST request is going to the /page2 endpoint rather than to the /home endpoint, where you have written the code for handling the form submission. We can fix this by just deleting the action attribute, as this means the form will post to then endpoint that loaded it - in this case /home.
Secondly, Flask sessions cannot be used without setting a secret key to encrypt the session. This can be done by assigning a value to app.secret_key, like so:
app = Flask(__name__)
app.secret_key = b"my_secret_key"
Finally, instead of passing the string to the template like so: render_template('page2.html', stringval = stringval), (note also that this should be stringval_get = stringval), you can access the session object directly from templates already. So, in all, we can change your application code to:
app.py:
from flask import Flask, render_template, request, session
app = Flask(__name__)
app.secret_key = b"my_secret_key"
#app.route('/', methods=['GET', 'POST'])
def home():
if request.method == 'POST' and 'stringval' in request.form:
session["stringvalue_topass"] = request.form.get('stringval')
return render_template('page2.html')
return render_template("home.html")
#app.route('/page2', methods=['GET', 'POST'])
def page2():
return render_template('page2.html')
And your templates to:
home.html:
<!doctype html>
<h1>Enter Value </h1>
<div class="main">
<form class="pure-form" method="POST">
stringval:<br>
<input type="text" name="stringval"><br>
<button type="submit" class="pure-button pure-button-primary" value="Submit">Submit!</button>
</form>
</div>
</body>
page2.html:
<!doctype html>
<h1>You have selected </h1>
<div class="main">
{% if 'stringvalue_topass' in session %}
<pre>
{% print(session["stringvalue_topass"]) %}
</pre>
{% endif %}
</div>
</body>
I've been using python flask as well as html, in order to create a small website, (just as a hobby while I'm off school), I created a form in html, and saved it within the templates folder of the project. I also then added a function within the python script, so when a button is clicked of the webpage it would redirect the user back to the home page (index.html), however when I have tested the webpage and clicked on the button on the webpage (with the flask server running) a "400 bad request" page is shown
Python Code:
#Python code behind the website
import datetime
from flask import Flask, session, redirect, url_for, escape, request, render_template
print ("started")
def Log(prefix, LogMessage):
timeOfLog = datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S" + " : ")
logFile = open("Log.log", 'a')
logFile.write("[" + timeOfLog + "][" + prefix + "][" + LogMessage + "] \n")
logFile.close()
app = Flask(__name__)
#app.route('/')
def my_form():
print ("Acessed index")
return render_template("index.html")
#app.route('/', methods=['POST'])
def my_form_post():
text = request.form['text']#requests text from the text form
processed_text = text #does nothing
user = "" #use poss in future to determin user
logFile = open("MessageLog.msglog", 'a')#opens the message log file in append mode
logFile.write(text + "\n")#stores the inputted message in the message log file
logFile.close()
#print (text)
Log("User Message", (user + text))#uses the main log file to store messages aswell as errors
print ("Accessing index")
return render_template("test.html")
#app.route('/test', methods=['POST'])
def test():
#text = request.form['text']
print ("Test page function")
#return "hello"
return render_template("index.html")
if __name__ == '__main__':
app.debug = True
app.run(host='0.0.0.0')
HTML code:
-->
<body>
<h1>Test Page</h1>
<form method="POST">
<input type="submit" name="my-form" value="Send">
</form>
</body>
Stack Track:
You need to post your form to the correct URL:
<body>
<h1>Test Page</h1>
<form method="POST" action='/test'>
<input type="submit" name="my-form" value="Send">
</form>
</body>
By default if you don't add an action attribute to an HTML form it will just perform it's defined method to the URL you are currently on. You can add an action attribute to change that behavior.
You can also do this with the url_for() function. This is a bit safer as URL's tend to change more often than your view method names:
<body>
<h1>Test Page</h1>
<form method="POST" action="{{ url_for('test') }}">
<input type="submit" name="my-form" value="Send">
</form>
</body>
You pass the name of the view method (not it's URL) as a string to the function. Be careful to use the right quotes.
Note that it's slightly confusing to have 2 views for the same URL. Usually something like this is done although YMMV but consider it for your application:
#app.route('/someurl')
def some_view():
if request.method == "POST":
# handle POST
else:
# handle GET