I have the following flask application that displays a dashboard with various buttons. Each button executes a python function. After the execution of such a function I want the application to return to the dashboard. In order to give the user a simple log I want to output some string on the html page. For that thought about a tag above the buttons on the dashboard that get filled with the respective value. How can I do that?
Flask:
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def main():
return render_template('index.html')
#app.route('/something')
def do_something():
print("Hello")
return render_template('index.html', user="Successfully executed!")
if __name__ == "__main__":
app.run()
HTML:
<!DOCTYPE html>
<html>
<head>
<head>
<meta charset="UTF-8">
</head>
<title>MP Reporting</title>
</head>
<body>
<div value=user></div>
Your button
</body>
</html>
For flask template use "{{kwarg}}" i.e. in your example
<div>{{user}}</div>
will render as
<div>Successfully executed!</div>
In addition to other answers, I suggest using Flask's built-in message flashing which is simpler, and neater instead of passing variables to render_template manually. It's simple as that:
(template)
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div>{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
(flask view)
from flask import flash
flash("Successfully executed!")
You can get more information from here.
You can print variables using Jinja2.
To print out the variable user in your example add
{{ user }} in the html template.
If you send a list of items to the html you can output them by using a simple for:
{% for item in items %}
{{ item }}
{% endfor %}
Related
I have my server.py file, where i have:
from flask import Flask,render_template,url_for
app=Flask(__name__)
#app.route("/")
#app.route("/home")
def home():
return render_template("home.html",posts=posts,title="arroz")
if __name__=="__main__":
app.run(debug=False)
My home.html file has:
{%extends "layout.html"%}
{%block content%}
<!--here-->
{%endblock content%}
I want to execute some python code in a python file on the client side in the comment here on the home.html file. I can't just call regular python code from flask, because that would run on the server side. How can I run it on the client side?
My project's structure is the following:
|-server.py
|-pythonToExecuteOnClientSide.py
|-templates
|-home.html
This won't work since Python is not a web-app language supported by browsers. Everything that is client-side needs to be able to run on the client computer and for Python code you need to have Python installed on your computer.
The only option you have is to code your feature in JavaScript to let it run on the client side.
Why exactly do you want it to run on the client side? Maybe there is a different solution for your problem. Like a server-client program.
You are already executing python code on the client side.
{% pyton code %} <html> {% python %}.
to give you an example.
when you render your page you can pass a python variable named 'posts' to your page with the value "i did it"; along with a python variable named 'title' with the value "arroz".
return render_template("home.html", posts=posts, title=title)
you can display the value of those python variables like this:
{%extends "layout.html"%}
{%block content%}
{{ posts }} {{ title }}
{%endblock content%}
you can format the value displayed just like any other html content:
<p> {{ posts }} </p> <h1> {{ title }} </h1>
your final code should be
server.py
from flask import Flask,render_template,url_for
app=Flask(__name__)
#app.route("/")
#app.route("/home")
def home():
posts = None
title = "arroz"
return render_template("home.html",posts=posts,title=title)
if __name__=="__main__":
app.run(debug=False)
home.html
{%extends "layout.html"%}
{%block content%}
<p> {{ posts }} </p> <h1> {{ title }} </h1>
{%endblock content%}
I use Python flask for my web application. the application provide a CSV file to download. CSV file is the response in below code block. Also I need to send a variable to html template. How can I have two return value?
#application.route("/log_analysis", methods=['POST'])
def get_response():
output='The result of your query : '+str(i-1)+' . The full report is downloaded automatically.'
cw.writerows(csv_rows)
response = make_response(si.getvalue())
response.headers["Content-Disposition"] = f"attachment; filename={return_file_name}"
response.headers["Content-type"] = "text/csv"
return render_template('base.html',output=output)
return response, 200
The output will be shown in the html but the response in the second return doesn't work.
After reading your question, I think what you are looking for is something like flash messages. The variable content you are passing in, is just text and used to display a message.
Flash messages
You'll need to set this up in your base.html or whatever template you are rendering.
Template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link href="{{ url_for('static', filename='css/main.css')}}" rel="stylesheet">
</head>
<body>
<main>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</main>
</body>
</html>
from flask import render_template, url_for, flash, redirect
#application.route("/log_analysis", methods=['POST'])
def get_response():
output=f'The result of your query : {i-1} . The full report is downloaded automatically.'
cw.writerows(csv_rows)
response = make_response(si.getvalue())
response.headers["Content-Disposition"] = f"attachment; filename={return_file_name}"
response.headers["Content-type"] = "text/csv"
flash(output,'success')
return response, 200
You can also try and do something like alerts in html template
Am very much new to Flask & Python, so want to understand/clear my concepts. I have a webpage which i created using flask & wtforms. Html page is very simple having just single field & a submit button. I want to call a python script (test.py) itself or python function(pythonfunction()) when submit button is clicked. Also Is there a way from the webpage,whatever i enter , i can pass as an attribute to that python script (test.py)? help appreciated
**app.py**
from flask import Flask , render_template,flash,redirect,url_for,session,logging,request
from wtforms import Form,StringField,TextAreaField,PasswordField,validators,SelectField,TextAreaField
from wtforms.widgets import TextArea
import subprocess
import test
app=Flask(__name__)
#app.route ('/')
def index():
return render_template('home.html')
class testpython(Form):
testenter=StringField('Enter something')
#app.route ('/testpage',methods=['GET','POST'])
def testpage():
form=testpython(request.form)
return render_template('testpage.html',form=form,python=testfunc(testenter))
if __name__ == '__main__':
app.run(debug=True)
**test.py**
def pythonfunctiontest (self):
print data #<something i can print here from that text field in webpage>
return "all good"
**testpage.html**
{% extends 'sec_layout.html'%}
{% block body %}
{% from "includes/_formhelpers.html" import render_field %}
<form method="POST" action ="">
<div class="form-group">
{{render_field(form.testenter,cols="1", rows="5",class_="form-control")}}
</div>
<div class="input-bar-item input-bar-item-btn">
<button class="btn btn-info">Submit</button>
</div>
</form>
{% endif %}
{% endblock%}
sec_layout.html
<!DOCTYPE <!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>MY PAGE-TEST</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
</head>
<body>
{% include 'includes/_navbar.html' %}
<div class= "container">
{% block body %}{% endblock%}
</div>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" </script>
</body>
</html>
The question is very general so I will try and give you a steer and perhaps you might revisit this question later with a little more clarity.
Flask asks a server and renders webpages. I.e. it executes some code on the server and passes it to the client web browser. The client web browser can then execute client side code (i.e. Javascript) as the user is browsing and can pass data back to the server using submit forms (to different Flask routes) or via JavaScript AJAX requests (again to other Flask routes). So if you want to execute python script based on some input you will need a separate route.
Here is a simple example of an index page and a second route that will execute something else:
#app.route('/index')
def index():
""" very basic template render """
return render_template('index.html')
#app.route('/data-submit', methods=["POST"])
def calc():
data = request.form.information.data
# do something with data..
x = data + data
return render_template('new_page.html', x)
========= (index.html)
<html>
<body>
<form action="{{ url_for('app.calc') }}" method="POST">
<input name="information" type='text'>
<button name="submit">
</form>
</body>
</html>
Wrap whatever temp.py is doing in a function.
Place it in the same directory as flask.py. Call import temp in flask.py, then use temp.myfunction().
This question already has answers here:
How does the 'with' statement work in Flask (Jinja2)?
(2 answers)
Closed 4 years ago.
I was checking the message flashing in flask framework from here.
This is a basic example where a template file (Index.html) is used to provide the initial link and another template file (Login.html) creates the form.
The files are:
Login.html:
<!doctype html>
<html>
<body>
<h1>Login</h1>
{% if error %}
<p><strong>Error:</strong> {{ error }}
{% endif %}
<form action = "" method = post>
<dl>
<dt>Username:</dt>
<dd>
<input type = text name = username
value = "{{request.form.username }}">
</dd>
<dt>Password:</dt>
<dd><input type = password name = password></dd>
</dl>
<p><input type = submit value = Login></p>
</form>
</body>
</html>
Index.html:
<!doctype html>
<html>
<head>
<title>Flask Message flashing</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li<{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<h1>Flask Message Flashing Example</h1>
<p>Do you want to <a href = "{{ url_for('login') }}">
<b>log in?</b></a></p>
</body>
</html>
Flash.py:
from flask import Flask, flash, redirect, render_template, request, url_for
app = Flask(__name__)
app.secret_key = 'random string'
#app.route('/')
def index():
return render_template('index.html')
#app.route('/login', methods = ['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or \
request.form['password'] != 'admin':
error = 'Invalid username or password. Please try again!'
else:
flash('You were successfully logged in')
return redirect(url_for('index'))
return render_template('login.html', error = error)
if __name__ == "__main__":
app.run(debug = True)
The part that is confusing me is inside index.html. It's using with messages = get_flashed_messages() to get the messages from the session. I do not fully understand why it's using with? I know with is used for resources, files, streams etc to control the closing procedure (and for not leaving something open when something goes wrong etc). What's the resource it's accessing using with in this context?
I tried removing it (in this context) and an error occurred:
jinja2.exceptions.TemplateSyntaxError: Encountered unknown tag
'messages'.
Also, example use cases from programcreek.com does not use with with get_flashed_messages so what's the case here?
Jinja templates are not Python. with in a template is not a Python context manager, it just introduces a new scope; this code definesa new variable messages that is only visible until the endwith.
See the docs.
try to fix index.html
<!doctype html>
<html>
<head>
<title>Flask Message flashing</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<h1>Flask Message Flashing Example</h1>
<p>Do you want to <a href="{{ url_for('login') }}">
<b>log in?</b></a></p>
</body>
</html>
This question already has answers here:
Determine which WTForms button was pressed in a Flask view
(1 answer)
Validate WTForm form based on clicked button
(1 answer)
Closed 6 years ago.
Imagine I need to build a travel planning form like this:
Going from [_Picadily_Circus____]
Going to [_Marylebone_____]
(Starting by) (Arriving by) [5]:[30][pm]
Both (Starting by) (Arriving by) are submit buttons. The example is artificial to show a two-button usecase so let's not discuss usability.
How do I do this with Flask and WTForms?
How to see which button was actually pressed?
Your form's submit button's data value will be True if it was pressed. See very simple example below of a form with two submit buttons and a single input field.
from flask import Flask, render_template, flash
from flask.ext.wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'well-secret-password'
class MyForm(Form):
name = StringField(label='Name', validators=[DataRequired()])
starting = SubmitField(label='Starting')
ending = SubmitField(label='Ending')
#app.route('/', methods=['GET', 'POST'])
def index():
form = MyForm()
if form.validate_on_submit():
print "Starting data Value : {value}".format(value=form.starting.data)
print "Ending data Value : {value}".format(value=form.ending.data)
flash(
"You submitted name {name} via button {button}".format(
name=form.name.data,
button="Starting" if form.starting.data else "Ending"
)
)
return render_template('index.html', form=form)
if form.errors:
for error_field, error_message in form.errors.iteritems():
flash("Field : {field}; error : {error}".format(field=error_field, error=error_message))
return render_template('index.html', form=form)
if __name__ == '__main__':
app.run(debug=True)
Here's the template file index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<form method="POST" action="{{ url_for('index') }}">
{{ form.csrf_token }}
{{ form.name.label }} {{ form.name(size=20) }}
<br><br>
{{ form.starting }}
{{ form.ending }}
</form>
</body>
</html>