我尝试学习Flask,但我无法找到问题的答案:如果我使用GET作为Flask-的表单方法,有没有办法获得一个“干净”的URL,可以加入书签WTF插件?
如果我在模板中使用方法POST:
<form method="POST" action="">
浏览器中的URL不会改变,在Flask的调试模式中它将是:
http://127.0.0.1:5000/
如果我提交表格。
如果我使用方法GET,URL将如下所示:
http://127.0.0.1:5000/?name=test&submit=Submit&csrf_token=1453393786%23%23a327427d
但我想使用Flask-WTF插件制作表单,并在浏览器中找到一个漂亮的,可收藏的URL,如下所示:
http://127.0.0.1:5000/?name=test
这可能吗?
我试图在PHP中实现这样的目标:
<?php
if( $_GET["name"] ) {
echo "Hello, ". $_GET['name']. "!";
exit();
}
?>
<html>
<body>
<form action = "<?php $_PHP_SELF ?>" method = "GET">
Name: <input type = "text" name = "name" />
<input type = "submit" />
</form>
</body>
</html>
提交后,我收到了这个网址:
http://127.0.0.1/test.php?name=test
我可以复制此链接,将其发送给其他人,他或她可以使用浏览器打开它,并获得相同的结果。通过使用表单中的方法GET简单地完成。看看这个:
http://www.utrace.de/?query=8.8.8.8
使用Flask I cloud执行此操作:
http://127.0.0.1/query/8.8.8.8
但是,如果我使用多个参数呢?在PHP中它看起来像这样:
http://127.0.0.1/?para1=8.8.8.8¶2=US
我已尝试过,使用此代码(从Miguel Grinberg借出):
程序:
from flask import Flask, render_template
from flask.ext.wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import Required, Length
app = Flask(__name__)
app.config['SECRET_KEY'] = 'top secret!'
class NameForm(Form):
name = StringField('What is your name?', validators=[Required(),
Length(1, 16)])
submit = SubmitField('Submit')
@app.route('/', methods=['GET', 'POST'])
def index():
name = None
form = NameForm()
if form.validate_on_submit():
name = form.name.data
form.name.data = ''
return render_template('index.html', form=form, name=name)
if __name__ == '__main__':
app.run(debug=True)
模板:
<form method="GET" action="">
{{ form.name.label }} {{ form.name(size=16) }}
{% for error in form.name.errors %}
{{ error }}
{% endfor %}
<br>
{{ form.submit() }}
{{ form.hidden_tag() }}
</form>
{% if name %}
<h1>Hello, {{ name }}!</h1>
{% endif %}
答案 0 :(得分:1)
我建议将其分解为自己的观点。您应该使用CSRF表单,您应该尝试分离GET和POST接口。
迫使一段代码或函数执行多项操作有时可能看起来更干净,但会发生什么情况会增加可维护性成本并使事情变得不那么清晰。
你如何在Flask中这样做:
@app.route('/<name>/', methods=['GET'])
现在,这不会给你验证。您可以自己执行此操作,也可以使用Marshmallow库等https://marshmallow.readthedocs.org/en/latest/
在你的例子中,Marshmallow会有点矫枉过正,但如果你计划扩展你的API,那就太棒了。它将允许您采用更复杂的JSON blob并验证并将它们序列化为Python对象。
另外,我会研究为什么你在POST上使用GET。 POST应该用于在服务器上创建新数据,应该使用GET来获取该信息。
编辑(编辑后):
使用Flask I cloud执行此操作:
http://127.0.0.1/query/8.8.8.8 但是,如果我使用不止一个,那该怎么办? 参数?在PHP中它看起来像这样:
您可以像这样制作Flask视图:
@app.route('/<name>/<another_parameter>/<another>/', methods=['GET'])
def some_route_name(name, another_parameter, another):
但是,如果您想通过ONE表单完成所需的操作,则必须关闭CSRF。您的PHP示例未使用CSRF。
我建议:
1)按照我最初的建议创建一个新视图 2)在您使用表单的视图上,将其POST到自身,然后重定向到新视图,如下所示:
if form.validate_on_submit():
return redirect(url_for('name_of_new_view', name=form.name.data))
3)在这个新视图中,放置您的表单,但将表单POST到您的OLD视图。 POST时请确保包含CSRF令牌!像这里:
{{ form.csrf_token }}