3

I have a template (index.html) that I would like to display on GET and the same template, with a variable added, on POST.

app.py:

from flask import Flask, render_template
app = Flask(__name__)

@app.route("/")
def hello():
    return render_template("index.html")

@app.route("/", methods=["POST"])
def hello_():
    return render_template("index.html", string_="Success!")

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=4567)

index.html:

<html>
    <head>
        <script type="text/javascript" src="/static/jquery.js"></script>
    </head>

    <body>

    <button onclick="signIn();">Sign In</button>
    <h1>{{ string_ }}</h1>

    <script>
        function signIn() {
        var data = "data";

        $.ajax({
            type : "POST",
            data: JSON.stringify(data, null, '\t'),
            contentType: 'application/json',
            success: function(result) {
                console.log(result);
                }
              });
        }
    </script>
    </body>
</html>

traceback:

 * Running on http://0.0.0.0:4567/ (Press CTRL+C to quit)
127.0.0.1 - - [11/Dec/2015 11:16:17] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [11/Dec/2015 11:16:17] "GET /static/jquery.js HTTP/1.1" 304 -
127.0.0.1 - - [11/Dec/2015 11:16:21] "POST / HTTP/1.1" 200 -

I'm not receiving an error, but the variable string_ isn't appearing in the template on POST (after I click the button). It appears that the template I have set to render on POST isn't working.

Is it possible to render a different template in Flask based on request.method?

  • What do you mean by `it doesn't display the render_template under POST, either`? What do you get actually? – lord63. j Dec 11 '15 at 01:48
  • @lord63.j It only returns the template `index.html`, with no value for `name` –  Dec 11 '15 at 05:08
  • What's the result for `request.get_json()`, turn on the debug mode and print it to see if you get the right info. – lord63. j Dec 11 '15 at 05:19
  • @lord63.j `request.get_json()` was working all right; I re-phrased my question above. –  Dec 11 '15 at 19:29
  • It works right, because you log the result in the console after success, so the result won't show in the page. You can take a look at you console. – lord63. j Dec 12 '15 at 01:51

1 Answers1

1

It makes the most sense to split this into two distinct routes, one serving the GET and one serving the POST.

@app.route('/')
def index_as_get():
    return render_template('index.html', name="")

@app.route('/', methods=["POST"])
def index_as_post():
    r = request.get_json()
    name = r['name']
    return render_template('index.html', name=name)

Note that you actually have to invoke this behavior through a REST client that can invoke a POST request to your root page before you can notice anything.

Makoto
  • 104,088
  • 27
  • 192
  • 230
  • Thanks; I'll give it a shot and then accept if this works –  Dec 11 '15 at 05:09
  • Thanks for the input, but no luck. Also, I get `AssertionError: View function mapping is overwriting an existing endpoint function:` with this code. I can fix it by assigning a different function name to `index`. I did `index` and `index_`. Just FYI. Also, re-phrased my question above. –  Dec 11 '15 at 19:27
  • @Daniel: Right you are. Even in my example I had different names for that function. I've corrected it. – Makoto Dec 11 '15 at 20:04