如何获得可以在 Flask-WTF 中添加书签的“漂亮”URL?
How to get a “nice” URL that can be bookmarked in Flask-WTF?
我尝试学习 Flask,但我找不到问题的答案:如果我使用 GET 作为表单方法,有没有办法获得一个“干净”URL,可以添加书签使用 Flask-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>
提交后,我得到这个URL:
http://127.0.0.1/test.php?name=test
我可以复制这个link,发给别人,他或她可以用浏览器打开它,得到同样的结果。只需在表单中使用 GET 方法即可轻松完成。看看这个:
http://www.utrace.de/?query=8.8.8.8
使用 Flask 我云执行此操作:
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 %}
我建议将其纳入自己的观点。您应该对表单使用 CSRF,并且您应该尝试将 GET 和 POST 接口分开。
强制一段代码或函数做多项事情有时看起来更简洁,但实际上会增加可维护性成本并使事情变得不那么清晰。
如何在 Flask 中执行此操作:
@app.route('/<name>/', methods=['GET'])
现在,这并没有给你验证。您可以自己执行此操作,也可以使用 Marshmallow 等库:https://marshmallow.readthedocs.org/en/latest/
在您的示例中,Marshmallow 可能有点矫枉过正,但如果您打算扩展 API,那会很棒。它将允许您获取更复杂的 JSON blob,并将它们验证并序列化为 Python 个对象。
此外,我会调查您为什么使用 GET 而不是 POST。 POST 应该用于在服务器上创建新数据,GET 应该用于获取该信息。
编辑(编辑后):
With Flask I cloud do this:
http://127.0.0.1/query/8.8.8.8
But what, if I would use more than one
parameter? In PHP it would look like this:
您可以像这样创建 Flask 视图:
@app.route('/<name>/<another_parameter>/<another>/', methods=['GET'])
def some_route_name(name, another_parameter, another):
但是,如果你想用一个表单完成你想要的,你就必须关闭 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 放入旧视图。请确保在 POST 时包含 CSRF 令牌!喜欢这里:
{{ form.csrf_token }}
我尝试学习 Flask,但我找不到问题的答案:如果我使用 GET 作为表单方法,有没有办法获得一个“干净”URL,可以添加书签使用 Flask-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>
提交后,我得到这个URL:
http://127.0.0.1/test.php?name=test
我可以复制这个link,发给别人,他或她可以用浏览器打开它,得到同样的结果。只需在表单中使用 GET 方法即可轻松完成。看看这个:
http://www.utrace.de/?query=8.8.8.8
使用 Flask 我云执行此操作:
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 %}
我建议将其纳入自己的观点。您应该对表单使用 CSRF,并且您应该尝试将 GET 和 POST 接口分开。
强制一段代码或函数做多项事情有时看起来更简洁,但实际上会增加可维护性成本并使事情变得不那么清晰。
如何在 Flask 中执行此操作:
@app.route('/<name>/', methods=['GET'])
现在,这并没有给你验证。您可以自己执行此操作,也可以使用 Marshmallow 等库:https://marshmallow.readthedocs.org/en/latest/
在您的示例中,Marshmallow 可能有点矫枉过正,但如果您打算扩展 API,那会很棒。它将允许您获取更复杂的 JSON blob,并将它们验证并序列化为 Python 个对象。
此外,我会调查您为什么使用 GET 而不是 POST。 POST 应该用于在服务器上创建新数据,GET 应该用于获取该信息。
编辑(编辑后):
With Flask I cloud do this:
http://127.0.0.1/query/8.8.8.8 But what, if I would use more than one parameter? In PHP it would look like this:
您可以像这样创建 Flask 视图:
@app.route('/<name>/<another_parameter>/<another>/', methods=['GET'])
def some_route_name(name, another_parameter, another):
但是,如果你想用一个表单完成你想要的,你就必须关闭 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 放入旧视图。请确保在 POST 时包含 CSRF 令牌!喜欢这里:
{{ form.csrf_token }}