I am trying to build a simple Flask application that will run a web app that connects to a Postgres database.
However, when I run the code and click the submit button, the POST method does not work, so it does return the {{url_for('success]}} as specified. I have tried adding and removing several components.
I have methods=['GET', 'POST'] already.
app.py:
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.sql import func
app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']='postgresql://postgres:postgres#localhost/Jeopardy'
db=SQLAlchemy(app)
class Data(db.Model):
__tablename__="allc"
number = db.Column(db.Integer, primary_key=True)
category = db.Column(db.String())
question = db.Column(db.String())
answer = db.Column(db.String())
def __init__(self,number,category,question,answer):
self.number = number
self.category = category
self.question = question
self.answer = answer
#app.route("/")
def index():
return render_template("index.html")
#app.route("/success", methods=['POST','GET'])
def success():
if request.method=='POST':
category=request.form['category']
question=request.form['question']
answer=request.form['answer']
number=request.form['number']
print(email, height)
if db.session.query(Data).filter(Data.number == number).count()== 0:
data=Data(number,category,question,answer)
db.session.add(data)
db.session.commit()
return render_template("success.html")
if __name__ == '__main__':
app.debug=True
app.run()
index.html:
<html lang="en">
<title>Jeopardy</title>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device=width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="../static/style.css" rel="stylesheet" >
</head>
<body>
<div class="="container">
<img src="../static/logo.png" alt="Jeopardy" class ="logo">
<!-- #todo - message-->
<form action = "s{{url_for('success')}}" methods="POST">
<div class = " form-group">
<h3>Jeopardy Question</h3>
<input
type = "number"
name = "Index"
placeholder= "Type number" />
<input
type = "text"
name = "Question"
placeholder= "Type the Jeopardy question here" />
<input
type = "text"
name = "Answer"
placeholder= "Type the Jeopardy Answer here"/>
<button type = "submit"> Submit</button>
</form>
</div>
</body>
</html>
While running the code my app renders successfully, but when submitting a number the server does not register the input. When loading the success page separately, it loads.
In the terminal, I see: "POST /success HTTP/1.1" 404 -
You have a typo in your html
It should be method="post" and not methods="post"
EDIT:
Another typo in
action = "s{{url_for('success')}}"
Remove the "s"
here is typo:
<form action = "s{{url_for('success')}}" methods="POST">
change it to:
<form action = "{{url_for('success')}}" method="POST">
Related
I am new to Python and Flask. I am trying to use WTForm FlaskForm, and having problems with choices in SelectField. I am building my forms like this.
class FightForm(FlaskForm):
fight_id = StringField('fight_id', render_kw={'readonly': True})
fight_type_id = SelectField('fight_type_id',
choices=[(t.fight_type_id, t.type_name) for t in fight_type.query.all()], validate_choice=False, validators=[DataRequired()])
These choices appear to only load 1 time. If I go add a new fight_type, I have to stop the application and restart if for it to refresh.
Also, I found this answer, flask wtforms selectfield choices not update, but FlaskForm does not trigger the __init__ function this suggests.
I changed it temporarily to Form anyway and got an error saying fight_type_id does not belong to form (paraphrasing).
I would like for these to refresh every time I call the page.
I think you should take a look at the WTForms-SQLAlchemy extension.
The QuerySelectField dynamically loads all database entries based on a submitted database query. A column can be defined for the label of an entry. When the form is submitted, the selected object is automatically queried from the database and is returned by the field.
Flask (app.py)
from flask import (
Flask,
redirect,
render_template,
request,
url_for
)
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from flask_wtf.csrf import CSRFProtect
from wtforms.validators import InputRequired
from wtforms_sqlalchemy.fields import QuerySelectField
app = Flask(__name__)
app.secret_key = b'your secret here'
db = SQLAlchemy(app)
csrf = CSRFProtect(app)
class FightType(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False, unique=True)
class Fight(db.Model):
id = db.Column(db.Integer, primary_key=True)
type_id = db.Column(db.Integer, db.ForeignKey('fight_type.id'))
type = db.relationship('FightType', backref='fights')
class FightForm(FlaskForm):
type = QuerySelectField(
get_label='name',
query_factory=lambda: FightType.query.all(),
validators=[InputRequired()]
)
with app.app_context():
db.drop_all()
db.create_all()
types = [FightType(name=f'type-{i}') for i in range(10)]
db.session.add_all(types)
db.session.commit()
#app.route('/')
def index():
fights = Fight.query.all()
return render_template('index.html', **locals())
#app.route('/fight/new', methods=['GET', 'POST'])
def fight_create():
form = FightForm(request.form)
if form.validate_on_submit():
fight = Fight()
form.populate_obj(fight)
db.session.add(fight)
db.session.commit()
return redirect(url_for('index'))
return render_template('create.html', **locals())
#app.route('/fight/<int:fight_id>/edit', methods=['GET', 'POST'])
def fight_update(fight_id):
fight = Fight.query.get_or_404(fight_id)
form = FightForm(request.form, obj=fight)
if form.validate_on_submit():
form.populate_obj(fight)
db.session.commit()
return redirect(url_for('index'))
return render_template('update.html', **locals())
HTML (templated/index.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Index</title>
</head>
<body>
New
<ul>
{% for f in fights -%}
<li>
<a href="{{ url_for('fight_update', fight_id=f.id) }}">
{{ f.id }} - {{ f.type.name }}
</a>
</li>
{% endfor -%}
</ul>
</body>
</html>
HTML (templates/create.html, templates/update.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Fight</title>
</head>
<body>
<form method="post">
{{ form.csrf_token }}
{{ form.type.label }} {{ form.type() }}
<input type="submit" value="Go">
</form>
</body>
</html>
I need to display the value that was entered in a form after the user clicks the submit button. It displays it for a split second but when the page reloads it's gone
<html>
<html>
<head>
<link rel="stylesheet" href="{{url_for('static',filename='main.css')}}">
</head>
<body>
<title> Patent Info </title>
<form action="" method="POST" >
Enter Room Number <input type="number" name="getInput" id="data" min="1" max="5">
<input type="submit" onclick="c.value = getInput.value">
<h4>Going to Room: <output name="c"></output></h4>
</form>
from flask import Flask, render_template, request
from random import randrange
app = Flask(__name__)
#app.route("/")
def main():
return render_template('index.html')
#app.route('/', methods=['POST'])
def my_form_post():
input_nopol = request.form['getInput']
if request.method == 'POST':
with open('nopol.txt', 'w') as f:
f.write(str(input_nopol))
return render_template('index.html', nopol=input_nopol)
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=80)
I know i can do it if i change from type submit to type button but then my POST method dose not work
Try This
<h4>Going to Room: <output name="c">{{ nopol }}</output></h4>
Just add this below <h4>Going to Room: <output name="c"></output></h4>
<p>{{ nopol }}</p>
Submit button of the form is not working. After submitting the form,it should redirect to the next page but nothing is happening. On submit, it was supposed to redirect to the link localhost:5000/dashboard-data and then print the data on the web page. Please if anybody could help me. I have provided as much details as I could.
This is dashboard.py
import os
import random
import pandas as pd
from flask import Flask, render_template , request
import sqlite3
import matplotlib.pyplot as plt
import matplotlib
PEOPLE_FOLDER = os.path.join('static')
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = PEOPLE_FOLDER
data = pd.read_excel('C:\\Users\\Desktop\\Projects\\api\\Tweet_qlik_first.xlsx')
from sqlalchemy import create_engine
engine = create_engine('sqlite://', echo=False)
#app.route('/', methods=['GET', 'POST'])
def homepage():
if request.method=='GET':
matplotlib.use('Agg')
data.to_sql('users', con=engine)
topic_list=engine.execute("SELECT distinct Topic FROM users").fetchall()
count=engine.execute('''Select Topic,count(*) from users group by Topic''',).fetchall()
print(count)
x = []
y = []
for tr in count:
x.append(tr[0])
y.append(tr[1])
plt.bar(x,y)
plt.gcf().subplots_adjust(bottom=0.15)
plt.xlabel('Topics')
plt.ylabel('Tweet Count')
ax = plt.gca()
plt.setp(ax.get_xticklabels(), rotation=30, horizontalalignment='right')
plt.tight_layout()
x=random.randint(0,9999999)
img_name='plot'+str(x)+'.png'
plt.savefig('static/'+img_name)
full_filename = os.path.join(app.config['UPLOAD_FOLDER'], img_name)
tl=[]
for tr in topic_list:
tl.append(tr[0])
return render_template("main.html",topics=tl,img=full_filename)
#app.route('/dashboard-data',methods=['GET','POST'])
def result():
if request.method=='POST':
result=request.form["topic_list"]
topic_fcount=engine.execute('''Select Topic,"Follower Count" from users where Topic=?''',(str(result),)).fetchall()
return render_template("dashboard.html")
if __name__ == "__main__":
app.run(debug=True)
This is main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action = "/dashboard-data" method = 'POST'>
Topic
<select name="topic_list">
{% for each in topics %}
<option value="{{each}}" selected="{{each}}">{{each}}</option>
{% endfor %}
</select>
<input type="button" value="Submit"/>
</form>
</body>
<img src="{{ img }}" alt="User Image" >
</html>
This is dashboard.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for row in topic_fcount %}
{{row}}
{%endfor%}
</body>
</html>
Submit button of the form is not working. After submitting the form,it should redirect to the next page but nothing is happening.
Try changing the button to:
<input type="submit" value="Submit" />
You defined your button as a button, not as a submit.
You just need to edit your button from
<input type="button" value="Submit"/>
to
<input type="submit" value="Submit"/>
and you will have success.
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'm having troubles with Google App Engine. It is all set up (and working hour before), when I reconnected the Engine the form simply stop working, when I hit submit, the page goes to the server's page and nothing happens.
<!DOCTYPE html>
<html lang="en">
<body>
<form action="http://localhost:9080/sub" method="post">
<input type="email" name="email" placeholder="Email"/>
<input type="submit" value="Subscribe"/>
</form>
</body>
</html>
import webapp2
class SubscribeHandler(webapp2.RequestHandler):
def post(self):
self.response.headers['Content-Type'] = 'text/plain'
email = self.request.get("email")
if email == '':
self.response.out.write("no email")
self.response.out.write(email)
app = webapp2.WSGIApplication([('/sub', SubscribeHandler)], debug=True)