How to pass variables between HTML pages using Flask - python

I'm new to using Flask and I've just been trying to pass a variable between two web pages. The first is a simple form to accept a number with the second page just displaying what is entered.
HTML for the form page:
<!doctype html>
<html>
<body>
<form action ="{{ url_for('return_form', glon="glon") }}" method="post">
Galactic Longitude: <input type="text" name="glon">
<button type="submit">Submit</button>
</form>
</body>
</html>
HTML for the display page:
<!doctype html>
<body>
<p> {{ glon }} </p>
</body>
</html>
The Flask script currently looks like this:
from flask import Flask
from flask import render_template, url_for, request, redirect
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/form/', methods = ['GET', 'POST'])
def form():
if request.method == 'POST':
glon = request.form['glon']
#glat = request.form['glat']
return redirect(url_for('return_form', glon=glon))
return render_template('form.html')
#app.route('/return_form/<glon>', methods = ['GET', 'POST'])
def return_form(glon):
return render_template('return_form.html', glon=glon)
if __name__ == '__main__':
app.run()
At the moment, the second page just displays "glon" instead of the number passed to the form.
I simply want the variable to display on the second page, and eventually use it in the return_form function.

So i didn't got your approach.Below is what i did,I changed the code a bit. Hope this solves your problem.
main.py
from flask import Flask
from flask import render_template, url_for, request, redirect
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/form', methods = ['GET', 'POST'])
def form():
if request.method == 'POST':
glon = request.form['glon']
return render_template('display.html', glon=glon)
# #app.route('/return_form/<glon>', methods = ['GET', 'POST'])
# def return_form(glon):
# return render_template('return_form.html', glon=glon)
if __name__ == '__main__':
app.run()
index.html
<html>
<body>
<form action ="{{ url_for('form') }}" method="post">
Galactic Longitude: <input type="text" name="glon">
<button type="submit">Submit</button>
</form>
</body>
</html>
display.html
<!doctype html>
<body>
<p> {{ glon }} </p>
</body>
</html>

Related

Flask HTTP Method Not Allowed Message

from flask import Flask, render_template,request
app = Flask(__name__)
#app.route('/',methods=['post'])
def main():
if (request.method=="POST"):
text=request.form('write')
if(text==None):
text=""
else:
text=""
return render_template('form.html',text=text)
if __name__ == "__main__":
app.run(debug=True)
I want to receive only POST method. So I set method option to methods=["post"]. But it always sends HTTP 405 Not Allowed Method error.
<html>
<head>
<title>Using Tag</title>
</head>
<body>
<form method="POST">
<input type="text" name="write">
<input type="submit">
</form>
{{ text }}
</body>
</html>
I want to know reason why this application only sends HTTP 405 response.
To access the HTML form from / path you need to enable both GET and POST request in that route. Otherwise when you try to access the root path / from your browser, you will get the HTTP Method not allowed error.
app.py:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/', methods=['POST', 'GET'])
def main():
text = ""
if request.method == "POST":
text = request.form['username']
return render_template('form.html', text=text)
if __name__ == "__main__":
app.run(debug=True)
templates/form.html:
<html>
<head>
<title>Using Tag</title>
</head>
<body>
<form method="POST">
<input type="text" name="write">
<input type="submit">
</form>
{{ text }}
</body>
</html>
Output:
Explanation (Updated):
To access the form value use request.form['INPUT_FIELD_NAME'].
We are making GET and POST requests to the / route. So, we set GET and POST requests in the methods options of the / route. When we are viewing the page using the browser, we make GET request to that page. When we submit the form, we make POST request to that page. In this case, we are storing the form value in the text variable and pass the value to the template. For GET request we are showing the empty text value.
The above snippet is the same as the following snippet:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/', methods=['POST', 'GET'])
def main():
if request.method == "POST":
text = request.form['username']
return render_template('form.html', text=text)
elif request.method == "GET":
return render_template('form.html', text="")
if __name__ == "__main__":
app.run(debug=True)
References:
Flask documentation for request object

How to display and edit text files on the web page using python and Flask?

I want to build a simple web application based on Flask and Python for displaying and editing a text file in my directory path that I have created before on the web page. I have written the codes and can be run, but the results are not as expected. Everyone who can give me solutions is really appreciated.
from flask import Flask, request, render_template, redirect, url_for
from pathlib import Path
from os import listdir
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template('index.html')
#app.route('/', methods=['GET,POST'])
def my_form_post():
path=Path('/users/Devie Andriyani/EditFlask/days.txt') # set the path to your file here
if not path.exists():path.touch()
input_days = request.form['text_box']
if request.method == 'POST':
with open('/users/Devie Andriyani/EditFlask/days.txt', 'w') as f:
f.write(request.form.get('text_box',None))
return redirect(url_for('my_form_post'))
if __name__ == '__main__':
app.debug = True
app.run()
<!DOCTYPE html>
<head>
<title>Hello</title>
</head>
<body>
<form action="" method="POST">
<input name="text_box" value={{days}}>
<input type="submit">
</form>
</body>
</html>
And here's the result. I don't get the result as I expected. It should edit a text file
from flask import Flask, request, render_template
from os import listdir
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template('index.html')
#app.route('/', methods=['GET,POST'])
def my_form_post():
input_days = ''
if request.method == 'POST':
input_days = request.form['text_box']
with open('/users/Devie Andriyani/EditFlask/days.txt', 'w') as f:
f.write(str(input_days))
return render_template('index.html', days=input_days)
if __name__ == '__main__':
app.debug = True
app.run()
<!DOCTYPE html>
<head>
<title>Hello</title>
</head>
<body>
<form action="" method="POST">
<input name="text_box" value="{{ days }}">
<input type="submit">
</form>
</body>
</html>
I don't understand clearly what is your question but I have found some Erorrs in your code:
This is wrong
#app.route('/', methods=['GET,POST'])
you should write like this #app.route('/', methods=['GET','POST'])
also you didn't specify any element to display the days so then why you didn't see the output .
you should give some element like <p>{{days}}</p>

Flask/HTML question: Where does a request from an input text box in html arrive in app.route in flask? [duplicate]

This question already has answers here:
Get the data received in a Flask request
(23 answers)
Closed 2 years ago.
I'm new to flask and web programming in general. I'm trying a simple example. I have a HTML base template that shows a text box and a picture of an animal. The template is rendered by flask. The idea is that a user can type the name of a new animal in the text box and the picture changes to the new animal.
I tested the code. There is a problem - that the input text given in the html textbox doesn't seem to go to the proper app.route. Or at least I can't figure out (as I'm running on pythonanywhere and the print statements in the server don't show up on console).
Here is the code and the template. Please let me know what I'm doing wrong. Thanks!
Here is the flask_app.py:
from flask import render_template
from flask import request, redirect
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
imgname = "tiger2.png"
return render_template('untitled1.html', title='TIGER', fname=imgname)
#app.route('/', methods=['POST', 'GET'])
def imgshow(animal):
#assert request.method == 'POST'
#print("New request!")
animal = request.form['animal']
if animal.lower() == 'tiger':
imgname = 'tiger2.png'
elif animal.lower() == 'lion':
imgname = 'lion1.png'
elif animal.lower() == 'panther':
imgname = 'panther.png'
else:
imgname = 'lion1.png'
return render_template('untitled1.html', title=animal.upper(), fname=imgname)
And here is the template untitled1.html
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<!-- Serving an Image -->
<h1>Hello, World!</h1>
<form action="">
<label for="animal">Animal: </label>
<input type="text" id="animal" name="animal"><br><br>
</form>
<img src="{{ url_for('static', filename=fname ) }}" alt="Tiger">
</body>
</html>
Try this:
from flask import render_template
from flask import request, redirect
from flask import Flask
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'GET':
imgname = "tiger2.png"
title='TIGER'
else:
variants = {
'tiger': 'tiger2.png',
'lion': 'lion1.png',
'panther': 'panther.png'
}
animal = request.form.get('animal').lower()
imgname = variants.get(animal)
title = animal.upper()
return render_template('untitled1.html', title='TIGER', fname=imgname)
For me, the best approach is to use only the GET method:
from flask import Flask, render_template, request, redirect
app = Flask(__name__)
animals = {'tiger': 'tiger2.png', \
'lion': 'lion1.png', \
'panther': 'panther.png'}
#app.route('/')
def index():
animal = request.args.get('animal', 'tiger')
image = animals.get(animal, 'lion')
return render_template('untitled1.html', title=animal.upper(), fname=image)
The POST method is best when you need to do some processing (write data from the database) and then redirect to another GET route.
app.route registers that under the given web address (in your case \), the function listed just below be implemented. The problem is that you have two functions registered under the same route which means that the first registration is erased.
You don't need the first app.route. It basically should say that the default value of an animal is a tiger. The second function should be modified as below:
display_map = {
'tiger': 'tiger2.png',
'lion': 'lion1.png',
'panther': 'panther.png'
}
#app.route('/', methods=['POST', 'GET'])
def imgshow(animal):
if request.method == 'POST':
animal = request.form.get('animal', 'lion').lower()
imgname = display_map.get(animal, 'lion1.png')
return render_template('untitled1.html', title=animal.upper(), fname=imgname)
else:
return render_template('untitled1.html', title='TIGER', fname='tiger.png')
And you also need to actually submit results to the server.
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<!-- Serving an Image -->
<h1>Hello, World!</h1>
<form method="POST">
<label for="animal">Animal: </label>
<input type="text" id="animal" name="animal"><br><be>
<input type="submit" name="submit" value="submit">
</form>
<img src="{{ url_for('static', filename=fname ) }}" alt="Tiger">
</body>
</html>

String POST Request to Flask

I'm trying to implement a simple dashboard with Flask that will:
Accept a user text input, with a "submit" button. POST this user input to flask.
Flask accepts this input, does some stuff to it, then makes a GET request to another API.
This GET request returns data and shows it somehow (can just be console.log for now)
As an example, with the star wars API:
User inputs name of a Star Wars character (assume no spelling errors)
Flask reads this input name, and maps it to an ID number, because the Star Wars API accepts id numbers. Form a GET request to the Star Wars API, to get full character information.
For now, we can just console.log character information (e.g. "height", "mass", etc.)
What I have now:
app.py
from flask import Flask, jsonify, request, render_template
import random
import json
app = Flask(__name__)
#app.route("/")
def index():
return render_template('index.html')
#app.route("/form_example", methods=["GET", "POST"])
def form_example():
if request.method == "POST":
language = request.form("character_name")
starwars_dictionary = {"Luke Skywalker":"1", "C-3PO":"2", "R2-D2": "3"}
# starwars_dictionary is a dictionary with character_name:character_number key-value pairs.
# GET URL is of the form https://swapi.co/api/people/<character_number>
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
index.html
<!DOCTYPE html>
<html>
<head>
<title>py-to-JS</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>
<body>
<h3>Sample Inputs</h3>
<ul>
<li>Luke Skywalker</li>
<li>C-3PO</li>
<li>R2-D2</li>
</ul>
<form method="POST">
Enter Name: <input type="text" name="character_name"><br>
<input type="submit" value="Submit"><br>
</form>
</body>
</html>
In this current form, when I run the app, it returns "Method not allowed; this method is not allowed for the requested URL".
I'm not sure what I'm missing; it's probably just not wired together properly but I'm not sure what the proper syntax is.
Working version after implementing the accepted answer:
app.py
from flask import Flask, jsonify, request, render_template
import requests
import random
import json
app = Flask(__name__)
#app.route("/index", methods=["GET", "POST"])
def index():
#character_height = "" # init a default value of empty string...seems unwieldy
if request.method == "POST":
character_name = request.form.get("character_name")
# Map user input to a numbers
starwars_dictionary = {"Luke Skywalker":"1", "C-3PO":"2", "R2-D2": "3"}
char_id = starwars_dictionary[character_name]
url = "https://swapi.co/api/people/"+char_id
response = requests.get(url)
response_dict = json.loads(response.text)
character_height = response_dict["height"]
return render_template("index.html", character_height=character_height)
return render_template("index.html")
##app.route("/form_example", methods=["GET", "POST"])
#def form_example():
if __name__ == "__main__":
app.run(debug=True)
index.html
<!DOCTYPE html>
<html>
<head>
<title>py-to-JS</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>
<body>
<h3>Sample Inputs</h3>
<ul>
<li>Luke Skywalker</li>
<li>C-3PO</li>
<li>R2-D2</li>
</ul>
<form method="POST" action="/index">
Enter Name: <input type="text" name="character_name"><br>
<input type="submit" value="Submit"><br>
</form>
{{ character_height }}
</body>
</html>
Probably the form is posting to the / endpoint, because you didn't declare a form action.
Needs to be more like:
<form method="POST" action="/form_example">
Or if you want to get snazzy and use Jinja's url_for function:
<form method="POST" action="{{ url_for('form_example') }}">
EDIT: That said, you could handle this with a single route function:
#app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
language = request.form("character_name")
starwars_dictionary = {"Luke Skywalker":"1", "C-3PO":"2", "R2-D2": "3"}
# Logic to query remote API ges here.
else: # Assume method is GET
return render_template("index.html")
Then make the form action {{ url_for('index') }}

Python global variable not updating in real time flask

value=user_id is not taking the new value defined by def login():.for e.g. if the entered user_id from HTML page is 200, 300 and 100. The values will be assigned as 0, 200, 300. That is, when home page is displayed it will be showing user 0 for entered value 200, and for second time it is showing 200 for entered value 300 and for third time it is showing 300 for entered value 100.
I need a real time values i.e. for entered value 200 home page should have value 200, and for 300 it should be 300. Could anyone please help me with this? Please advice. Thanks in advance. Note: HTML code is not optimized.
from flask import Flask, render_template # Flask is the class within the flask library
from flask import request, redirect
user_id = int(0)
app = Flask(__name__) # Instance of the object Flask. __name__: this gets value of name of python script
#app.route('/', methods=["GET", "POST"]) # login page
def login():
if request.method == "POST":
global user_id
user_id = request.form['userid']
print(user_id)
return render_template("login.html")
#app.route('/home/') # This the URL i.e. home page
def home():
return render_template("home.html", value=user_id)
if __name__ == "__main__":
app.run(debug=True)
HTML Code for Login page here.
<!DOCTYPE html>
<html>
<head>
<title>Recommender System App</title>
<link rel="stylesheet" type="text/css" href="{{url_for('static',filename='css/main.css')}}">
</head>
<body>
<header>
<div class="container">
<h1 class="logo">Movie Recommender System</h1>
<strong><nav>
<ul class="menu">
</ul>
</nav></strong>
</div>
</header>
<form action="{{ url_for('login') }}" method="post">
<div class = "Login Fields">
<b>Username:</b> <input type="number" placeholder="Numbers only" name='userid'>
<p><b>Password:</b> <input type="password" placeholder="Enter Password" name= 'password' id="pwd"></p>
<input type="submit" onclick="check(this.form)" class="button">
</div>
<p></p>
<p></p>
<div>
<p>Test User IDs:</p>
<li>224</li>
<li>216</li>
<li>681</li>
<li>19</li>
<li>82</li>
<li>305</li>
<li>44</li>
<li>268</li>
<p>Password: 123Swaroop</p>
</div>
</form>
<script language="javascript">
function check(form)/*function to check userid & password*/
{
if(form.password.value == "123Swaroop")
{
window.open(href = "{{ url_for('home') }}")
}
else
{
alert("Wrong Password or User Id")/*displays error message*/
}
}
</script>
</body>
</html>
HTML code for home page here:
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
<link rel="stylesheet" type="text/css" href="{{url_for('static',filename='css/main.css')}}">
</head>
<body>
<header>
<div class="container">
<h1 class="logo">Welcome User: {{ value }}</h1>
<strong><nav>
<ul class="menu">
</ul>
</nav></strong>
</div>
</header>
<div class = "home">
<h1>Top Rated Movies</h1>
<p>This is test website</p>
</div>
</body>
</html>
You also need to call the global value within your home() function:
from flask import Flask, render_template, request, redirect
user_id = int(0)
app = Flask(__name__)
#app.route('/', methods=["GET", "POST"])
def login():
if request.method == "POST":
global user_id
user_id = request.form['userid']
print(user_id)
return render_template("login.html")
#app.route('/home/')
def home():
global user_id
return render_template("home.html", value=user_id)
if __name__ == "__main__":
app.run(debug=True)
However, using global variables is usually considered bad practice so you could also consider something like this:
from flask import Flask, render_template, request, redirect
app = Flask(__name__)
#app.route('/', methods=["GET", "POST"])
def login():
return render_template("login.html")
def get_user_id():
try:
if request.method == "POST":
user_id = request.form['userid']
return user_id
else:
# Handle error or do something else
except:
# Handle error or do something else
#app.route('/home/')
def home():
try:
return render_template("home.html", value=get_user_id())
except:
# Handle error or do something else
if __name__ == "__main__":
app.run(debug=True)

Categories

Resources