简体   繁体   中英

Flask template won't re-render

I am trying to re-render a flask template (index.html) once an event is triggered. Here is a simplified version of what I'm trying to do: the page is rendered initially and the console displays some text ("Initial Data"). Then the user clicks a button and the page re-renders with some new data ("New Data"). In the real version the python code does some heavier processing on the data so it is not possible to do this with pure HTML/JS, I do need to re-render the page.

This is the current setup:

main.py

from flask import Flask, request, render_template, redirect, Response, url_for    

app = Flask(__name__)

@app.route('/', methods = ['GET'])
def index():
    return render_template(("index.html"), val="Initial Data")

@app.route('/newData', methods = ['GET', 'POST'])
def newData():
    return redirect(url_for("index", val="New Data"))

if __name__ == '__main__':
    app.run()

templates/index.html

<script src='https://code.jquery.com/jquery-3.3.1.min.js'></script>
<body>
    <button onclick='sendData()'>send data</button>
</body>
<script>
    window.onload = function () { console.log({{val}}) };
    function sendData() {
        var str = 'This is some data';
        $.ajax({
            url: '/newData',
            type: 'POST',
            data: str,
            success: function () { console.log('success') },
            error: function (error) { console.log(error) }
        })
    }
</script>

Currently what's happening is "Initial Data" is appearing in the console when the page is initially rendered (as expected), the button click calls the function, and then nothing happens to the template. I want "New Data" to appear in the console next, showing that the template has been re-rendered, but this is not happening. I know that the python function newData is being called, but the index.html is not being re-rendered with the new parameter. I've tried various options for that line, such as return render_template("index.html", val="New Data") and return redirect("index.html", val="New Data") , but nothing has re-rendered the template with the new data.

Thanks.

You cannot use redirect this way. When you use redirect, it will redirect to the the flask view and then will run all the code in that view including the return render_template("index.html", val="Initial Data")

You could try and use get parameters for that:

@app.route('/<val>', methods = ['GET'])
def index(val): 
    return render_template(("index.html"), val=val)

@app.route('/newData/<val>', methods = ['GET', 'POST'])
def newData(val):
    return redirect(url_for("index", val=val))

Alternatively you could achieve this task with your existing ajax code if you would like by doing the following:

from flask import request
@app.route('/newData', methods = ['GET', 'POST'])
def newData():
    return request.data # this will access the data you sent using ajax 
                        # and return it back in the response

in your js code:

window.onload = function () { console.log({{val}}) };
    function sendData() {
        var str = 'This is some data';
        $.ajax({
            url: '/newData',
            type: 'POST',
            data: str,
            success: function (res) { console.log(res) }, 
              // res is the response from the server 
              // (from return request.data)
            error: function (error) { console.log(error) }
        })
    }

As @shifloni points out you can't do it that way. And if you could the AJAX call would only return the http render_template into the Javascript as a variable so it would not refresh your browser. This simplest method I can see is reorganising to:

@app.route('/', methods=['GET'], defaults={'val': 'Initial Data'})
@app.route('/<val>', methods=['GET'])
def index(val):
    return render_template(("index.html"), val=val)

and in your HTML doing it like this:

<body>
    <button onclick='sendData()'>send data</button>
</body>
<script>
    var sendData = function() {
        var strData = 'This is some data';
        urlGet = {{ url_for('app.index') }} + '/' + strData
        location.href = urlGet;
    };
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM