Using Python 2.7 and Flask how do I automatically respond to forms? I'm new to using Flask. Specifically, I'd like to render a basic calender on a Flask server and once a date/week is selected print this in the console.
The screen shot below shows I can see this form with the server running and to illustrate I've only included a calender and text input field. On selecting a date/week nothing happens - I only see the dictionary output (highlighted in the red rectangle, bottom image) once I type and press enter within the text field. After which the data is printed in the console and cleared from the form; I'd like the data to remain once entered too.
Screen shot and code shown:
from flask import Flask, render_template, jsonify, request
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def index():
print request.form
return render_template("index.html")
if __name__ == "__main__":
app.run(debug = True)
and form:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<form action="/", method="post">
Date:<br>
<input type="week" name="date" step="1" min="2015-W30" value="2015-W9">
<br>Name:<br>
<input type="text" name="name"><br>
</form>
</body>
</html>
Related
I am trying to get value from textbox on html webpage and print it in test.py file.
There are three files:
app.py
test.py
index.html
can someone please help?
app.py:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route("/")
def main():
return render_template("index.html")
#app.route("/", methods=["GET","POST"])
def get_provider():
dp = request.form["provider"]
dp_lower_case = dp.lower()
return dp_lower_case
if __name__ == '__main__':
app.run(debug=True)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ALMA PROCESS FLOW</title>
</head>
<body>
<form method="POST">
<label style="position:relative; left:5px; bottom:15px;"> Data Provider:</label>
<input name ="provider" type="text"">
<input type="submit" value="Generate"/>
</form>
</body>
</html>
test.py
from app import get_provider
provider = app.get_provider()
print(provider)
When you don't specify a method for a route, it defaults to a GET. This means that your code currently has 2 handlers for when your home page is loaded.
Since your form is doing a post, drop the 'GET' in the methods list i.e. change
#app.route("/", methods=["GET","POST"])
to
#app.route("/", methods=["POST"])
Better yet, you should combine everything i.e. change your code to
#app.route("/", methods=["GET","POST"])
def main():
# When it is a GET
if request.method == "GET":
return render_template("index.html")
# When it is a POST (user has submitted your form)
elif request.method == "POST":
dp = request.form["provider"]
''' Alternatively, you can use
dp = request.values.get("provider")
I prefer it because this way, I can provide a
default value in case the form parameter has no value i.e
dp = request.values.get("provider", "default provider")
'''
dp_lower_case = dp.lower()
return dp_lower_case
So, I am building a webapp which takes a link from a shopping website then runs it through a python script which interprets the data, stores it in a database and that populates a table for reference.
I am running into a couple issues:
if I put the link into the front end input (html) then submit it just takes me to "page isn't working HTTP error 405". I'm not sure what to do about that one.
the more pressing issue is that even though I believe I routed the input properly through flask I get this issue when I run the python script alongside the frontend
"RuntimeError: Working outside of request context."
I tried some of the advice mentioned in these existing posts to no avail:
Sending data from HTML form to a Python script in Flask
Connecting python script with html button and flask
I also tried changing the script itself to use getvalue() instead of getvalue when associating it as an input variable for the python script to work with.
this is my route code from app.py
#app.route("/", methods=['POST'])
def getvalue():
HTML_Info = request.form['data_bridge']
return HTML_Info
code for the HTML input
<form name="passdata" action="{{ url_for('getvalue') }}" method="POST">
<input type='text' name="data_bridge" placeholder="paste shoe link here">
<input type="submit">
</form>
and the python code just imports the app file and the getvalue function and then assigns it to a variable.
if you guys could help me sort this out I would greatly appreciate it.
I assume you want to take an input (e.g. shoe link) from the user and then do some operations based on the input.
To access the HTML form from / path you need to enable both GET and POST requests 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__)
def get_value_related_info(value):
return f"You have entered {value}"
#app.route('/', methods=['POST', 'GET'])
def getvalue():
if request.method == "POST":
HTML_Info = request.form['data_bridge']
return get_value_related_info(HTML_Info)
return render_template('form.html', text="")
if __name__ == "__main__":
app.run(debug=True)
Output:
Before form submission:
After form submission:
templates/form.html:
<html>
<head>
<title>Form example</title>
</head>
<body>
<form name="passdata" action="{{ url_for('getvalue') }}" method="POST">
<input type='text' name="data_bridge" placeholder="paste shoe link here">
<input type="submit">
</form>
</body>
</html>
Explanation:
I have mocked the functionality on the user input in get_value_related_info method.
References:
Flask documentation for request object
App.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="." method="post">
Search: <input type="text" name="search">
<input type="submit" value="Show">
</form>
</body>
</html>
main.py
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/CmpPr')
def cmpP():
return render_template('CmpPr.html')
#app.route('/CmpSpes')
def cmpS():
return render_template('CmpSpes.html')
#app.route('/App', methods=['POST', 'GET'])
def App():
search = request.form['search']
return render_template('output.html', n=search)
#app.route('/Gro')
def Gro():
return render_template('Gro.html')
if __name__ == '__main__':
app.run(debug=True)
I have created multiple html pages
I want to print the message, request from TextBox(above code) and print to another html page
I tried using request.form.get('search') but its returning null
And if I use request.form.get('search', FALSE or TRUE) it returns FALSE or TRUE
I have also used if else loop to specify GET and POST method, still it shows the same error
Can anyone please help me on this
Thank You
Firstly, your form action should point to the view that handle the form data (i.e. /App):
<form action="/App" method="post">
Secondly, you should only obtain the form data when the request's method is POST, since you have set method="post" in the template. Also, you will need to render the App.html that contains the form when request method is GET:
#app.route('/App', methods=['POST', 'GET'])
def App():
if request.method == 'POST': # get form data when method is POST
search = request.form['search']
return render_template('output.html', n=search)
return render_template('App.html') # when the method is GET, it will render App.html
P.S. The error you got is explained clearly that there isn't a key called search in the form data.
I am trying to create a basic form in Flask that will take in the input, manipulate it and then return the output. I am running into the issue that when I am running the terminal and trying to make my app work on the http://127.0.0.1:5000/ server, the files are not visible. Not sure where the bug is?
This is how I have my files organized:
/Users/eas/Desktop/grota/templates/index.html
/Users/eas/Desktop/grota/templates/age.html
/Users/eas/Desktop/grota/app.py
This is the app.py file
from flask import Flask, render_template,request
app = Flask(__name__)
#app.route('/send',methods = ['GET','POST'])
def send():
if request.method == 'POST':
age = request.form['age']
return render_template('age.html',age=age)
return render_template('index.html')
if __name__ == '__main__':
app.run()
This is the index.html file
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
</head>
<body>
<h1>How old are you?</h1>
<form method="POST" action = "/send">
<div class = "form-group">
<input type="text" name = "age">
</div>
<input class="btn btn-primary" type="submit" value="submit">
</form>
</body>
</html>
This is the age.html file
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>Your age is{{age}}</h1>
</body>
While looking for a problem, which I try to solve I found your question. For a solution that includes full code (with py and 2 HTML files) you can see my repl.it : https://repl.it/#AlperenAtik/NaturalShortActivecell#main.py
The problems are:
In the first function, you routed your loop to "/send" page. This is why your send page did not appear. The route of the first function needs to be "/"
In the index file, the source route was shown as '/send'. Whenever I changed it to / the script worked without a problem
The other commentators already mentioned your triggering function has an indentation mistake. When host and port added appropriately, your script would work.
for ones who love the harder way- seeing things in stackoverflow- not in action, I am adding the codeblocks. Enjoy.
for main.py
from flask import Flask, render_template,request
app = Flask(__name__)
#app.route('/',methods = ['GET','POST'])
def send():
if request.method == 'POST':
age = request.form['age']
return render_template('age.html',age=age)
return render_template('index.html')
if __name__ == '__main__':
app.run(host = '0.0.0.0', port = 8080
I left the host as '0.0.0.0' and port as 8080. If you are running Python on a terminal, you may try (host = '127.0.0.1', port:5000').
for templates/index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
</head>
<body>
<h1>How old are you?</h1>
<form method="POST" action = "/">
<div class = "form-group">
<input type="text" name = "age">
</div>
<input class="btn btn-primary" type="submit" value="submit">
</form>
</body>
</html>
for templates/age.html
<html>
<head>
</head>
<body>
<h1>Your age is {{age}}</h1>
</body>
You did not set the root route.
Or you open http://127.0.0.1:5000/send
Or you could use this quick and dirty fix (as you see in decorators now both / and /send are taken into account):
from flask import Flask, render_template,request
app = Flask(__name__)
#app.route('/',methods = ['GET'])
#app.route('/send',methods = ['GET','POST'])
def send():
if request.method == 'POST':
age = request.form['age']
return render_template('age.html',age=age)
return render_template('index.html')
if __name__ == '__main__':
app.run()
If you do not handle the '/' route nothing will happen when you open http://127.0.0.1
If you explain more clearly what is the result that you want to obtain I can help better.
Try going here: http://127.0.0.1:5000/send
If that doesn't work, what error are you getting in either your console or in your browser?
EDIT:
I just tried it, and it worked. Try reloading the page in a new tab in your browser, and see if it still occurs. This error has to do with the naming of your inputs on the webpage and the way you index your form with request.form['age']
I just started learning Flask, and as a practice project I wanted to build a simple site that asks the user for their name, and greets them by their name on a new page. I have been unable to get a user's name through a form, and display it on a new page due to to a 'Bad Request' error. My code is below.
This is my index page with the form on it:
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<h1>Practice index page</h1>
<h2>Welcome to my practice web page.</h2>
<form action = "/firstname">
<p>What's your name?</p>
<input type = "text" name = "yourname"><br>
<input type = "submit" value = "Submit">
</form>
</body>
</html>
This is my application.py file:
from flask import Flask
from flask import render_template, request, redirect
app = Flask(__name__)
#app.route('/')
def hello_world():
return render_template('index.html')
#app.route('/firstname')
def first_name():
yourname = request.form['yourname']
return render_template('firstname.html', name = yourname)
And this is my firstname.html file:
<!DOCTYPE html>
<head>
<title>My name is</title>
</head>
<body>
<h1>Hello</h1>
<h2>Your name is {{name}}.</h2>
</body>
The index page loads fine. The firstname.html template also loads fine when the user's name is hardcoded, it's only when I get it from the form that problems arise.
I have been at this for a few hours, watched YT videos, Googled like crazy, and still can't figure out what's wrong, so I would really appreciate some help!
By default, a Flask route only answers to GET requests. You can tell the first_name view to answer both GET and POST requests like so:
#app.route('/firstname', methods=['GET', 'POST'])
def first_name():
yourname = request.form['yourname']
return render_template('firstname.html', name = yourname)
You also need to set the form method to POST so that yourname is sent as form data (readable in request.form) and not as a URL parameter (readable in request.args).
<form action = "/firstname" method="POST">
<p>What's your name?</p>
<input type = "text" name = "yourname"><br>
<input type = "submit" value = "Submit">
</form>
Use request.args['yourname'] instead of request.form['yourname']
Your index.html form is calling /firstname url with get method and name argument as query string
GET /firstname?yourname=Sunny HTTP/1.1
so you need to access query parameters with request.args['yourname'] & not with request.form['yourname']
You need to pass variables as dict and not directly.
Like this
#app.route('/firstname')
def first_name():
yourname = request.form['yourname']
return render_template('firstname.html', **{"name": "yourname"})