Reputation: 611
I have a simple web page where the user selects a file from their computer and then presses an "Upload" button, after which a python script will be initiated with that file as an input.
However, I'm trying to get it so that if the user is uploading a file that will throw an error, a Flash message will show on the same page (without any redirection). In my current attempt, the flash message isn't showing when I choose to upload a purposefully erroneous file.
Also, as another question, is it possible to (within app.py) check for certain backend python error messages that will arise once I initiate the script (the ones that will show in the terminal)?
Anyways, here is the relevant code:
app.py:
@app.route("/", methods=['GET', 'POST'])
def upload():
if request.method == 'POST':
if 'file' not in request.files:
flash("No file chosen", 'danger')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('No selected file', 'danger')
return redirect(request.url)
elif not allowed_file(file.filename):
flash('Incorrect file extenstion. Must be .TXT!', 'danger')
return redirect(request.url)
elif file:
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
#
# Process the file (omitted here)
#
proc = subprocess.Popen('python author_script.py {} -p {} -s {} -m {}'.format(file.filename, period, space, affiliation), shell=True, stdout=subprocess.PIPE)
time.sleep(0.5)
return redirect(url_for('results'))
else:
# THIS PART IS NOT WORKING!
return redirect(request.path)
flash('There is an affiliation missing from your Place list.', 'danger')
return render_template('index.html', template_file=app.config['TEMPLATE_FILE'])
html template (layout.html):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Author Script</title>
<link rel="stylesheet" type="text/css" href="static/main.css" />
</head>
<body>
{% include 'includes/_navbar.html' %}
{% block body %}{% endblock %}
{% 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 %}
</div>
<!-- Scripts -->
<script src="js/jquery.min.js"></script>
<script src="js/skel.min.js"></script>
<script src="js/util.js"></script>
<script src="js/main.js"></script>
</body>
</html>
Upvotes: 4
Views: 12684
Reputation: 749
To show the flash messages, you need to specify a space for it. Probably you forget to add space for the flash messages. I encourage you to check out the documentation.
You can do it by creating
messages.html
paste the following code in it
{% 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 %}
{% if error %}
<div class="alert alert-danger">{{error}}</div>
{% endif %}
{% if msg %}
<div class="alert alert-success">{{msg}}</div>
{% endif %}
Make sure you call this messages.html inside the layout.html. Like this
{% include 'includes/_messages.html' %}
to make it show more beautiful you can put it in a like this
<div class='container'>
{% include 'includes/_messages.html' %}
{% block body %}{% endblock %}
</div>
Upvotes: 2
Reputation: 51
https://github.com/pallets/flask/issues/1168
This link suggests configs of APPLCATION_ROOT or caches would solve/"fix" the problem. Try these out firsts.
But what really did it for me was adding get_flashed_message in the methods.
from flask import get_flashed_messages
@app.route('/')
def upload():
get_flashed_messages()
....
Upvotes: 3
Reputation: 1308
Would it help if you do the flash message first and then the redirect? Like this:
flash('There is an affiliation missing from your Place list.', 'danger')
return redirect(request.path)
edit:
@app.route("/", methods=['GET', 'POST'])
def upload():
if request.method == 'POST':
if 'file' not in request.files:
flash("No file chosen", 'danger')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('No selected file', 'danger')
return redirect(request.url)
elif not allowed_file(file.filename):
flash('Incorrect file extenstion. Must be .TXT!', 'danger')
return redirect(request.url)
elif file:
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
try:
#
# Process the file (omitted here)
#
proc = subprocess.Popen('python author_script.py {} -p {} -s {} -m {}'.format(file.filename, period, space, affiliation), shell=True, stdout=subprocess.PIPE)
time.sleep(0.5)
return redirect(url_for('results'))
except Exception as e:
print("type error: " + str(e)) # --> to answer your question on showing errors in console
flash('There is an affiliation missing from your Place list.', 'danger')
return redirect (request.path)
return render_template('index.html', template_file=app.config['TEMPLATE_FILE'])
Upvotes: 3