I am using:
Consider this, isolated, example of the behavior I am pondering on:
from flask import Flask, url_for, render_template_string
app = Flask(__name__)
@app.route('/hi/', methods=['POST'])
@app.route('/hi/<var>')
def hi(var):
return ''
@app.route('/')
def index():
return render_template_string('''
<html>
<head>
<title>GET or POST</title>
</head>
<body>
<form action="{{ url_for('path') }}">
<input type='SUBMIT' value='GET'>
</form>
<form action="{{ url_for('path') }}" method='POST'>
<input type='SUBMIT' value='POST'>
</form>
</body>
</html>''')
@app.route('/path/', methods=['GET', 'POST'])
def path():
return str(url_for('hi', var='Hello', var2='xyz'))
To make my intentions clear, I will briefly describe what is happening and what I am striving to understand:
/hi/
endpoint has an 'optional' parameter (<var>
), which is accepted only via GET request. 'Plain' (i.e. without arguments)/hi/
endpoint can only be accessed via POST method./path/
endpoint can be accessed via both GET and POST http methods. And it just returns path forhi
generated viaurl_for('hi', var='Hello', var2='xyz')
- Now, I would expect
/path/
to return the same string, regardless of which method was used to access it (GET or POST). But it is not the case: for GET it returns/hi/Hello?var2=xyz
(as I, actually, would expect), but for POST I am getting/hi/?var=Hello&var2=xyz
(which strikes me as odd behavior).
Through trials and errors I was able to find out that adding POST to methods allowed for /hi/<var>
fixes the issue (/hi/Hello?var2=xyz
is returned by /path/
for both GET and POST), i.e.:
@app.route('/hi/', methods=['POST'])
@app.route('/hi/<var>', methods=['GET', 'POST'])
def hi(var):
...
I hope, someone would be able to explain the following, for me:
- Why is this (
/path/
returns different values for POST and GET) happening? - Is it possible to avoid this behavior, without allowing POST on
/hi/<var>
?