'Flask.flash messages not available through extended template

I am having trouble with sending flashed messages to a route that extends its layout from another template. This message shows up just fine if use the message in the layout.html which makes me believe that rendering login.html first will render layout.html and use the flashed message there and not pass it to my /login route. How are you able to call this message in an extended template? I am using the jijna with syntax taken from here to be able to have the message variable available within my mainblock. Flask's documentation does not specify this either.

app.py

@app.route("/login", methods=["POST", "GET"])
def login():
    
    # Forget any previous user
    if session.get("user_id"):
        session.pop("user_id")

    if request.method == "POST": 

        # Create connection cursor
        cursor = mysql.connection.cursor()

        # Query database for email
        cursor.execute("SELECT id, email, password FROM users WHERE email = %s", [request.form.get("email")])
        row = cursor.fetchone()
        print(row)
        if row is None:
            print("WHY")
            flash("Invaid user")
            return redirect("login")

My layout.html

<!DOCTYPE html>

<html lang="en">

    <head>
        <title>Hoook - {% block title %}{% endblock %}</title>
        <meta charset="utf-8">
        <meta name="viewport" content="initial-scale=1.0, width=device-width">
        <link href="/static/favicon-16x16.png" rel="icon">
        <link href="/static/style.css" rel="stylesheet">
        <!-- Scripts -->
        <script src="https://kit.fontawesome.com/542c2d099e.js" crossorigin="anonymous"></script>
        <script src="/static/mainJS.js"></script>
    </head>

    <body>
        <div class="page-wrapper">
            <header>
                <nav class="main-navbar">
                {% if request.path == "/login" %}
                    <div class="navbar-container login-container">
                {% else %}
                    <div class="navbar-container">
                {% endif %}
                        <div>
                            {% if request.path == "/login" %}
                                <a href=""><img src="/static/hoook_logo_blue.png" alt="Hoook Logo" height="50" width="150"></a>
                            {% else %}
                                <a href=""><img src="/static/hoook_logo.png" alt="Hoook Logo" height="50" width="150"></a>
                            {% endif %}
                        </div>
                        {% if request.path != "/login" %}
                            <div>
                                {% if session["user_id"] %}
                                    {# change nav bar for logged in users #}
                                {% else %}
                                    {# work on this nav bar for unlogged in users #}
                                    {% if request.path == "/signup" %}
                                        <a class="navbar-link" href="/login">Sign in</a>
                                    {% endif %}
                                {% endif %}
                            </div>
                        {% endif %}
                    </div>
                </nav>
            </header>
        </div>

        <main>
            {% if request.path == "/login" %}
                <div class="top-container signup-container">
            {% else %}
                <div class="top-container">
            {% endif %}
            {% with messages = get_flashed_messages() %}
            {% block main %}{% endblock %}
            {% endwith %}
                </div>
        </main>

        <footer>

        </footer>
    </body>


</html>

My login.html

{% extends "layout.html" %}

{% block title %}
    Login
{% endblock %}

{% block main %}
    <div class="login-div">
        <div>
            <h1 class="color-control">Sign in to Hoook</h1>
        </div>
        <div class="login-input-bx">
            <form action="/login" method="post" autocomplete="off">
                <div class="form-control login-form-control">
                    <label class="login-label color-control" for="email">Email address</label>
                    <input class="login-input" type="text" name="email" id="email" required autofocus>
                </div>
                <div class="form-control login-form-control">
                    <label class="login-label color-control" for="password">Password</label>
                    <input class="login-input" type="password" name="password" id="password" required readonly onfocus="this.removeAttribute('readonly')">
                </div>
                <button class="btn btn-login" type="submit">Sign in</button>
            </form>
        </div>
        {% if messages %}
            {% for msg in messages %}
                <div class="flashed-messages-div">
                    <p class="signup-para" id="login-flashed-messages">Error: {{ msg }}</p>
                </div>
            {% endfor %}
        {% endif %}
        <div class="signup-link-div">
            <p class="color-control signup-login-font">New to Hoook? <a class="signup-link-anchor" href="/signup">Create an account</a>.</p>
        </div>
    </div>
{% endblock %}

Update
I guess I could do something like make_response instead as seen here. and just use:

        response = make_response(render_template("login.html", message = "Invalid user"), 302)
        return response

However I am curious if there is a way to pass the flashed message through instead.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source