WTForms を使用してモデルのリストからフォームを作成するにはどうすればよいですか?
-
21-12-2019 - |
質問
のリストがあります Prediction
モデル。それらをフォームにバインドして、ポストバックできるようにしたいと考えています。投稿でホーム/アウェイスコアをスコアに関連付けるようにフォームを構成するにはどうすればよいですか? Prediction
モデルの id
フォームにバインドする各アイテムのフィールド?
ビュー
@app.route('/predictor/',methods=['GET','POST'])
@login_required
def predictions():
user_id = g.user.id
prediction= # retrieve prediction
if request.method == 'POST':
if form.validate() == False:
flash('A score is missing, please fill in all predictions')
render_template('predictor.html', prediction=prediction, form=form)
else:
for pred in prediction:
# store my prediction
flash('Prediction added')
return redirect(url_for("predictions"))
# display current predictions
elif request.method == 'GET':
return render_template('predictor.html', prediction=prediction, form=form)
形状
class PredictionForm(WTForm):
id = fields.IntegerField(validators=[validators.required()], widget=HiddenInput())
home_score = fields.TextField(validators=[validators.required()])
away_score = fields.TextField(validators=[validators.required()])
テンプレート
<form action="" method="post">
{{form.hidden_tag()}}
<table>
{% for pred in prediction %}
<tr>
<td>{{pred.id}}</td>
<td>{{form.home_score(size=1)}}</td>
<td>{{form.away_score(size=1)}}</td>
</tr>
{% endfor %}
</table>
<p><input type="submit" value="Submit Predictions"></p>
</form>
データを正しくバインドできません POST
. 。投稿データにすべての要素が欠落しているため、必要なバリデーターは継続的に失敗します。 必須 田畑。
解決
予測のリスト内の項目にバインドするサブフォームが必要です。
説明したフォームでは、1 つの予測のみを送信できます。反復可能な予測をバインドしており、それぞれについてホームとアウェイの予測が必要であるように見えるため、矛盾があるようです。実際、現状ではポストバックすることはありません id
分野。これにより、常にフォームの検証が失敗します。必要なのはサブフォームのリストだと思います。そのようです:
# Flask's form inherits from wtforms.ext.SecureForm by default
# this is the WTForm base form.
From wtforms import Form as WTForm
# Never render this form publicly because it won't have a csrf_token
class PredictionForm(WTForm):
id = fields.IntegerField(validators=[validators.required()], widget=HiddenInput())
home_score = fields.TextField(validators=[validators.required()])
away_score = fields.TextField(validators=[validators.required()])
class PredictionListForm(Form):
predictions = FieldList(FormField(PredictionForm))
ビューは次のようなものを返す必要があります。
predictions = # get your iterable of predictions from the database
from werkzeug.datastructures import MultiDict
data = {'predictions': predictions}
form = PredictionListForm(data=MultiDict(data))
return render_template('predictor.html', form=form)
フォームを次のように変更する必要があります。
<form action='my-action' method='post'>
{{ form.hidden_tag() }}
{{ form.predictions() }}
</form>
これで、 <ul>
と <li>
それが FieldList が行うことなので、アイテムごとに。スタイルを設定して表形式にするのはあなたにお任せします。少し難しいかもしれませんが、不可能ではありません。
POST では、各予測のホームとアウェイのスコアを含むフォームデータ辞書を取得します。 id
. 。これらの予測をバインドして、 SQLアルケミー モデル。
[{'id': 1, 'home': 7, 'away': 2}, {'id': 2, 'home': 3, 'away': 12}]
他のヒント
{% for key in di_RAA %}
<tr>
<td><form id="Run" action="{{ url_for('index') }}" method="post">
<input type="submit" class="btn" value="TEST" name="RUN_{{key}}">
</form></td>
</tr>
{% endfor %}
複数のボタンに対する他の簡単なソリューションを提供します。FieldList は優れていますが、各ボタンの名前とトリガー機能を取得するのは困難です。
from wtforms import fields
from wtforms.fields import FieldList, FormField
from wtforms import validators
いくつかのヒント: インポートを追加し、インポート エラー メッセージを削除する可能性があります。