claudiadast
claudiadast

Reputation: 611

Flask Flash message not showing after redirecting to the same page

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

Answers (3)

murat yal&#231;ın
murat yal&#231;ın

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

cranberrysauce
cranberrysauce

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

gittert
gittert

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

Related Questions