2016-01-21 21 views
0

我嘗試學習Flask,並且找不到問題的答案:如果我使用GET作爲Flask-WTF插件的表單方法,是否有辦法獲得「乾淨」的URL,該標籤可以添加書籤?如何獲得可在Flask-WTF中添加書籤的「漂亮」網址?

如果我在一個模板中使用POST方法:

<form method="POST" action=""> 

在瀏覽器中的URL不會改變,在瓶的調試模式將是:

http://127.0.0.1:5000/ 

如果我提交表單。

如果我使用GET方法,該URL應該是這樣的:

http://127.0.0.1:5000/?name=test&submit=Submit&csrf_token=1453393786%23%23a327427d 

但我想用砂箱WTF插件,使形式和在瀏覽器中得到一個不錯的,書籤的網址像這樣:

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 

隨着瓶我雲這樣做:

http://127.0.0.1/query/8.8.8.8 

但是,如果我想使用多個參數的更多?在PHP它應該是這樣的:

http://127.0.0.1/?para1=8.8.8.8&para2=US 

我已經試過了,用這個代碼(由米格爾·格林貝格借出):

計劃:

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 %} 

回答

1

我建議把它歸入自己的觀點。您應該使用CSRF表單,並且應該嘗試分離GET和POST接口。

強制一段代碼或函數有時可能看起來比較乾淨,但是會增加可維護性成本並使事情變得不那麼清晰。

你會怎麼做這在瓶:

@app.route('/<name>/', methods=['GET']) 

現在,這不會給你的驗證。你可以自己做這個,或者使用像棉花糖這樣的圖書館:https://marshmallow.readthedocs.org/en/latest/

在你的例子中,Marshmallow可能會矯枉過正,但是如果你打算擴展你的API,它會很棒。它將允許您採用更復雜的JSON blob並驗證並將它們序列化爲Python對象。

此外,我會研究爲什麼你使用GET通過POST。應該使用POST在服務器上創建新數據,GET應該用於獲取該信息。

EDIT(編輯之後):

隨着瓶我雲這樣做:

http://127.0.0.1/query/8.8.8.8 但是,如果我想使用一個以上的 參數?在PHP它應該是這樣的:

你會作出這樣的瓶觀點:

@app.route('/<name>/<another_parameter>/<another>/', methods=['GET']) 
def some_route_name(name, another_parameter, another): 

但是,如果你想完成你想要一種形式的東西,你就必須把CSRF關閉。您的PHP示例沒有使用CSRF。

我的建議是:

1)創建一個新的觀點,因爲我本來建議 2)用表格視圖,已張貼到自身,然後重定向到新的觀點,像下面:

if form.validate_on_submit(): 
    return redirect(url_for('name_of_new_view', name=form.name.data)) 

3)在這個新的觀點,把你的形式,但有一個表單POST到您的舊觀點。確保在POST時包含CSRF令牌!喜歡這裏:

{{ form.csrf_token }} 
+0

謝謝你,快速回答瑞恩!我是一個絕對的初學者,我的英語「破碎」。我再次編輯了我的問題,並添加了一個簡單的PHP示例和一個示例鏈接。也許在Python/Flask中沒有這樣的東西。 –

+0

我已添加到我的答案。我仍然會建議使用兩個視圖!只要做一個重定向到書籤頁。在我看來,這真的是最乾淨的方式! –

+0

是的,你是對的!重定向將會訣竅。我認爲有一種更簡單的方法來做到這一點(比如在PHP中),但是這樣做,我有更多的工作,但也更多地控制URL的外觀。非常感謝瑞恩! –