2014-02-16 28 views
2

我很努力地弄清楚如何完成與表中另一個元素相關聯的獨特表單字段實例。對於一個人爲的例子,這裏的下面的代碼:來自HTML表格中相同表單類的多個WTForm字段?

from flask import Flask, render_template, request 
from flask.ext.wtf import Form 
from wtforms import TextField, BooleanField 

app = Flask(__name__) 

app.debug = True 
app.config['SECRET_KEY'] = 'secret' 

class Person(Form): 
    fname = TextField('First Name') 
    phone = TextField('Phone Number') 
    email = TextField('Email Address') 
    active = BooleanField('Active') 

@app.route("/", methods=['GET', 'POST']) 
def guest(): 
    names = ['Bob', 'Joe', 'Jason', 'John'] # this could be a list, or data returned from a db query, previous POST data, or whatever 
    form = Person() 
    if request.method == 'POST' and form.validate_on_submit(): 
     return str(form.data) 

    return render_template('index.html', names=names, form=form) 

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

我的模板:

<html> 
<body> 
<form action="" method="post"> 
<table border="1"> 
    <thead> 
     <tr> 
      <th>Name</th> 
      <th>Telephone Number</th> 
      <th>Email Address</th> 
      <th>Active</th> 
     </tr> 
    </thead> 
    <tbody> 
     {% for n in names %} 
     <tr> 
      <td>{{ n }}</td> 
      <td>{{ form.phone }}</td> 
      <td>{{ form.email }}</td> 
      <td>{{ form.active }}</td> 
     </tr> 
     {% endfor %} 
    </tbody> 
</table> 

很明顯的是,在HTML中,name參數在每個每個輸入元素表格行都是完全相同的,因爲正在使用相同的表單字段,所以在「POST」時,如果輸入電話號碼,那麼該電話號碼現在填充表中的所有名稱行。 「激活」複選框也一樣。我也嘗試生成一個表單實例列表並將該列表傳遞給模板,但它似乎沒有像我預期的那樣工作。這似乎好像我在這一點上的選項有:

  1. 不要使用WTForms這個(參見下面的註釋)
  2. 使用WTForms FieldList中+ FormField(我不認爲這會工作無論是作爲這些需要命名鍵vs任意鍵,所以我會遇到完全相同的問題。)
  3. 以某種方式使用HiddenFields(甚至沒有想到這將如何工作)。

我知道,我可以通過模板手動創建<input type>元素融入表,並將其分配基於w不同的名稱/ ID的,但這不會覺得很習慣,再加上我不得不代碼在我自己的驗證。

回答

2

您通常會通過在多字典對象包含表單數據作爲第一個參數的形式:

form = UpdateWidgetForm(request.form) 

這確實要求POST數據的形式的窗口小部件相匹配;每個小部件將檢查該多字典,並用一些預填充的數據提取它需要呈現的內容。

或者,您可以通過在值作爲關鍵字參數,但這需要你自己驗證輸入,轉換的任何值向右類型:

number = request.form.get('widget_number') 
try: 
    number = int(number) 
except ValueError: 
    abort(404) 
policy = request.form.get('widget_policy') 
if policy not in ('foo', 'bar'): 
    abort(404) 

form = UpdateWidgetForm(widget_number=number, widget_policy=policy) 

How Forms get data的文件中。

如果您需要在一個頁面中生成多個表單,每個唯一的,來自同一個表單對象,您需要給它們每個唯一的前綴與Form(prefix=..)參數。

+0

感謝您的迴應Martijn。我已經花了很多時間在這裏嘲笑(re:將[MultiDict](http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.MultiDict)傳遞給表單)和I'米仍然有點卡住。我寧願不開始一個不必要的長評論線程,所以你會打開聊天或電子郵件的線程嗎?謝謝。 –

+0

我的理解有點進一步(我認爲)。我最終不認爲這(我試圖完成)甚至可能與wtforms。 MultiDict在具有多個值的情況下使用相同的鍵進行操作 - 此實例中的鍵與字段名稱(因此生成的HTML中的輸入元素中的「name」參數)相對應。我想要的是完全相反 - 從同一個Form類生成多個字段,每個字段都具有基於其他輸入的唯一名稱。 –

+0

@JohnJensen:然後對'Form()':'UpdateWidgetForm(prefix ='unique_prefix')'使用'prefix'參數來區分表單。 –

相關問題