I I am getting a 500 error when I click submit for the following view. Why am I getting this error and how do I fix it?
from flask import Flask, render_template
from flask import request, jsonify
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def homepage():
if request.method == 'POST':
f1 = request.form['firstVerb']
f2 = request.form['secondVerb']
return render_template('index.html', f1, f2)
return render_template('index.html')
if __name__ == "__main__":
app.run();
<form class="form-inline" method="post" action="">
<div class="form-group">
<label for="first">First word</label>
<input type="text" class="form-control" id="first" name="firstVerb">
</div>
<div class="form-group">
<label for="second">Second Word</label>
<input type="text" class="form-control" id="second" name="secondVerb" >
</div>
<button type="submit" class="btn btn-primary">Run it</button>
</form>
{{ f1 }}
{{ f2 }}
First off when you are getting a 500 error you should consider running the app with debug mode. You are building this app and while you are debugging, it is very useful to have this on to show you what happens when an error happens.
if __name__ == "__main__":
app.run(debug=True)
Now this gets you something more exciting:
127.0.0.1 - - [08/Jul/2015 14:15:04] "POST / HTTP/1.1" 500 -
Traceback (most recent call last):
...
File "/tmp/demo.py", line 11, in homepage
return render_template('index.html', f1, f2)
TypeError: render_template() takes exactly 1 argument (3 given)
There is your problem. You should refer to the documentation for render_template and see that it really only accepts one positional argument (the template name), but the rest of the arguments (in **context) msut be provided as keyword arguments. Otherwise there would be no references to the variables that were being referred to in the template, so fixing that call to:
return render_template('index.html', f1=f1, f2=f2)
Would provide the correct f1 and f2 to the template, thus solving the problem at hand.
For future reference, problems like these can be solved by reading the Flask documentation. Also, please go through this entire Flask tutorial to help you grasp the basics of this framework.
Related
I'm trying to get information from a form to my python file and then put into a template. Thing is, i know the form is working but i couldn't show it into the template.
Form here:
<div class="container" id="cont1">
<form action="http://127.0.0.1:5000/areas" method="POST" enctype="multipart/form-data">
<label for="author">Autor</label>
<input type="text" id="author" name="author"><br><br>
<label for="intro">Introdução</label>
<input type="text" id="intro" name="intro"><br><br>
<label for="content">Conteúdo</label>
<input type="text" id="content" name="content"><br><br>
<input type="file" id="planilha" name="planilha" accept=".csv"><br><br>
<input type="submit" value="Enviar">
</form>
</div>
then i try to get the data in app.py:
#app.route('/areas', methods=['GET', 'POST'])
def areas():
if request.method == "POST":
#app.context_processor
def f1():
aut = request.form.get['author']
intr = request.form['intro']
cont = request.form['content']
return dict(a=aut, i=intr, c=cont)
return render_template("areas.html")
else:
return render_template("areas.html")
I know it's working because i tried it out of the route and it showed what the form had. Now when i try into the route:
AssertionError
AssertionError: A setup function was called after the first request was handled. This usually indicates a bug in the application where a module was not imported and decorators or other functionality was called too late.
To fix this make sure to import all your view modules, database models and everything related at a central place before the application starts serving requests.
The decorator was the solution i found to get the data so i could place into templates like this:
<text>{{a}}</text>
The error is caused by the incorrect usage of the decorator. You don't need a decorator to pass variables to templates. render_template also accepts arguments which you can directly pass into your HTML file.
The following should work:
#app.route('/areas', methods=['GET', 'POST'])
def areas():
if request.method == "POST":
aut = request.form['author']
intr = request.form['intro']
cont = request.form['content']
return render_template("areas.html", a=aut, i=intr, c=cont)
else:
return render_template("areas.html")
I'm trying to run a simple Flask application based on multiple simple tutorials. My goal is to finish a full tutorial and manipulate the code to build a search web app that connects to a SQL server database.
However, when I try running the code and provide an integer input, the POST method is not working, so it will not return a {{value}} as specified.
I've tried adding and removing several components: adding in the action='/' on the HTML, and trying to run the code as well without it. That didn't make a difference.
I have methods=['GET', 'POST'] already.
I even tried {{ url_for('/') }} and that just gave me an Internal Server Error.
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
#app.route('/hello')
def hello():
return "My flask app"
#app.route('/', methods=["GET", "POST"])
def home():
if request.method == "POST":
value = int(request.form["number"])
add_one = value + 1
return render_template('index.html', string="WORLD!", value=add_one)
return render_template('index.html', string="WORLD!")
if __name__ == "__main__":
app.run()
HTML:
<body>
<div class="container">
<h1>Hello, {{string}}</h1>
<br>
<form action='/' role="form" method="post" onsubmit="return false;">
<div class="form-group">
<input type="number" class="form-control" name="number" placeholder="Enter a number" required>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<p>The calculated number is {{value}}</p>
<br>
</div>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
</body>
While running the code my app renders successfully, but when submitting a number the server does not register the input.
I don't even receive an error. All I see in the terminal is "GET / HTTP/1.1" 200.
By removing onsubmit="return false;" attribute of the form in the HTML.
And by restarting your app and reload the HTML.
It should be working.
This question already has answers here:
Flask - POST Error 405 Method Not Allowed
(3 answers)
Closed 3 years ago.
I am attempting to create a basic login page on a raspberry pi, but when I try to login to the page I keep getting a 405 error. I have researched the issue but it seems to only appear if you aren't using the correct methods, but since it's a login screen POST and GET should be more than sufficient.
Python
from flask import Flask
from flask import Flask, flash, redirect, render_template, request, session, abort
import os
app = Flask(__name__)
#app.route('/')
def home():
if not session.get('logged_in'):
return render_template('login.html')
else:
return "Hello Boss!"
#app.route('/login', methods=['POST', 'GET'])
def do_admin_login():
if request.form['psw'] == 'password' and request.form['id'] == 'admin':
print ("Hey ya!")
else:
print('wrong password!')
return home()
if __name__ == "__main__":
app.secret_key = os.urandom(12)
app.run(debug=True,host='0.0.0.0', port=80)
HTML
<!DOCTYPE html>
<html>
<body>
<h1>Please login</h1
<form method="POST">
<input name="id" type="text" placeholder="Enter UserID">
<br>
<input name="psw" type="password" placeholder="Enter Password">
<input type="submit">
</form>
</body>
</html>
I have been redirected to a different question which resolves it through changing the action part of the however mine does not have action so this should not be the same issue. I have attempted adding an action element to it but that has not changed anything
The problem is that you need to specify the action attribute in HTML:
<form method="POST" action="{{url_for('do_admin_login')}}">
<input name="id" type="text" placeholder="Enter UserID">
<br>
<input name="psw" type="password" placeholder="Enter Password">
<input type="submit">
</form>
As you may notice that I used url_for function to generate a URL to the given endpoint with the method provided ( do_admin_login() in this case ). So it is worth to mention that you need to change your statement return home() to return url_for("home").
I tried this approach to pass the form input variable to function via url_for method. But its not working. can anyone check and let me know whats wrong in this code.
Function:
#app.route('/report_data/<year>/<week>', methods = ['POST'])
def report_data(year,week):
print year
print woy
HTML Code :
<html>
<body>
<form action="{{ url_for('report_data', year=n_year, week=n_woy) }}" method="post">
<h3> Enter the details </h3>
Year :
<input type="text" name="n_year"> <br>
<br>
Week :
<input type="text" name="n_woy"> <br>
<br>
<input type="submit" value="Submit"> <br>
</form>
</body>
</html>
Issue:
Getting "None" for both variable.
Firstly, How do you provide year, week values before submitting them in your HTML code ?
Did you render the HTML template in your function? If not, how does your flask function knows that you were seeking from that specific form?
If this is your Flask app code -
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/report_data', methods = ['POST', 'GET'])
def report_data():
if request.method == 'POST':
result = request.form
query_year = result['n_year'].encode('ascii', 'ignore')
query_week = result['n_woy'].encode('ascii', 'ignore')
print(query_year, query_week)
return render_template('so_test.html')
if __name__ == '__main__':
app.run(debug=True)
And opened the URL -
http://127.0.0.1:5000/report_data
And I get this picture.
Once I post the data, I can see this data in my Flask app console.
('2018','08')
I am trying to call a function from another python file. I have imported that function. When i call the function externally it works as expected.
But when i try to call the function before returning a render_template or a redirect , i get a 500 error.
I know i am doing something wrong but i am not sure what. Any kind of help will be highly appreciated.
from flask import Flask, render_template, request, redirect, url_for
from content_man import Content,Page_Content
from url_trigger import trigger
TEST_TOPIC = Content()
PAGE_TOPIC = Page_Content()
app = Flask(__name__)
#app.route('/',methods=["GET","POST"])
def homepage():
return render_template("main.html")
#app.route('/dashboard/',methods=["GET","POST"])
def dashboard():
return render_template("dashboard.html", TEST_TOPIC=TEST_TOPIC)
#app.route('/test/', methods=["GET","POST"])
def test():
if request.method == "POST":
selected_list = request.form.getlist("to_run")
print (selected_list)
return redirect(url_for('trigger',selected_list=selected_list))
else:
return render_template("test.html", PAGE_TOPIC=PAGE_TOPIC)
#app.route('/trigger/', methods=["GET","POST"])
def trigger():
data = request.args.getlist('selected_list')
t = trigger(data)
return "hey"
if __name__ == "__main__":
app.run()
The error is in #app.route('/trigger/', methods=["GET","POST"]) where i am trying to call the function trigger.
My url_trigger python file contains the below simple definition:
def trigger(my_list=[], *args):
for i in my_list:
print (i)
The HTML file for the page test is as:
<div class="container">
<form method="post" action = "{{ url_for('test') }}">
{% for row_index in range(PAGE_TOPIC['Critical BP']|count) %}
<div class="checkbox">
<label><input type="checkbox" name="to_run" value="{{ PAGE_TOPIC['Critical BP'][row_index] }}">{{ PAGE_TOPIC['Critical BP'][row_index] }}</label>
</div>
{% endfor %}
<div>
<label><input type="submit" /></label>
</div>
</form>
</div>
You import a function named trigger, but you also a define a function named trigger in the module where you do the import. When trigger calls trigger, it is calling itself, and it accepts no arguments. You need to rename one of the functions, or do the import as import url_trigger and then refer to the imported function as url_trigger.trigger.