2017-12-18 16 views
0

イメージごとに1つずつ複数のフォームを生成し、イメージと対応するフォームをリスト内のタプルとしてパッケージ化しています。Flask-WTF:提出時に同じデータを返す同じクラスの複数のフォーム

このリストはJinjaに渡され、各タプルは展開され、フォームを介して投票するためのリストに各画像とフォームが挿入されます。

私の問題は、特定のフォームのいずれかをクリックすると、そのボタンがクリックされたようにすべてのフォームが戻ることです。

したがって、実際には、1つの画像を投票することで、他のすべての画像に対してそのボタンがクリックされたかのように動作します。

私は正式なフォームを作成しようとしています。フォームを印刷しようとしましたが、そのデータをコンソールに返します。これを行うと、各フォームに固有のアドレスがあり、すべてのフォームがform.field.data属性に同じデータ(True/False)を表示します。 誰かが私がここで起こっていることを発見するのを助けることができますか?

フォーム:

class VoteForm(FlaskForm): 
    upvote = SubmitField('vote up') 
    downvote = SubmitField('vote down') 

ルート:

@index_mod.route('/', methods = ['GET', 'POST']) 
def index(): 
    pics = Pic.select().order_by(Pic.score.desc()) 

    pics_and_forms = [] 

    for pic in pics: 
     voteform = VoteForm() 
     #tuple of pic and corresponding form 
     pics_and_forms.append((pic, voteform)) 

    for pic, form in pics_and_forms: 
     if form.validate_on_submit(): 
      if form.upvote.data: 
       pic.score += 1 
       pic.save() 
      if form.downvote.data: 
       pic.score -= 1 
       pic.save()    

    return render_template('index.html', pics_and_forms = pics_and_forms) 

神社:

<ul> 
    {% for pic, form in pics_and_forms %} 
    <li> 
     <b>{{ pic.name }} </b> 
     <i>Submitted by {{ pic.user.username }}</i> 
     Score: {{ pic.score }} 
     <img src="/pic/get/{{ pic.uuid }}" style="width:128px;" > 

     <form method="post" action=" {{ url_for('index_mod.index') }}"> 
     {{ form.csrf_token }} 
     {{ form.upvote }} 
     {{ form.downvote }} 
     </form> 

    </li> 
    {% endfor %} 
</ul> 

EDIT

だから私がいることを考え出しますよ私は戻ってくる投稿要求でクリックした特定のフォームが指定されていないようにしたいので、私はページに多くのフォームを埋め込むことができます。

代わりに、詳細を隠しフィールドに埋め込み、フラスコ要求オブジェクトを使用して隠しフォームからそのフィールドを取得する予定です。

私はむしろFlask-WTFをこれに完全に使用しますが、動的に複数のフォームをページに追加して実際にクリックされたフォームを取得するようなエレガントな方法はないようです。

答えて

0

一度に1つのフォームしか送信していないので、実際には1つのフォームオブジェクトを処理する必要があります。私はあなたが投票しているPicのIDを含むURLにPOSTするのがより良いアプローチだと思っています。そして、アップ/ダウンの投票はクリックされた送信ボタンからキャプチャされます。

私はこの説明するためにコードリファクタリングしました:

app.pyを

from flask import Flask, render_template, redirect, url_for 
from flask_wtf import FlaskForm 
from wtforms import SubmitField 


app = Flask(__name__) 
app.secret_key = 'secret' 


class VoteForm(FlaskForm): 
    upvote = SubmitField('vote up') 
    downvote = SubmitField('vote down') 


@app.route("/", methods=['GET']) 
def index(): 

    form = VoteForm() 

    pics = [ 
     { 
      "name": "test", 
      "user": {"username": "test"}, 
      "score": 1, 
      "uuid": 'test' 
     }, 
     { 
      "name": "test2", 
      "user": {"username": "test"}, 
      "score": 2, 
      "uuid": 'test2' 
     } 
    ] 

    return render_template("index.html", form=form, pics=pics) 


@app.route("/pic/<id>/vote", methods=['POST']) 
def vote(id): 

    form = VoteForm() 

    if form.validate_on_submit(): 
     if form.upvote.data: 
      print("Upvote for pic {}".format(id)) 
     if form.downvote.data: 
      print("Downvote for pic {}".format(id)) 

    return redirect(url_for('index')) 


if __name__ == "__main__": 
    app.run(debug=True) 

index.htmlを

<ul> 
    {% for pic in pics %} 
    <li> 
     <b>{{ pic.name }} </b> 
     <i>Submitted by {{ pic.user.username }}</i> 
     Score: {{ pic.score }} 
     <img src="/pic/get/{{ pic.uuid }}" style="width:128px;" > 

     <form method="post" action="{{ url_for('vote', id=pic['uuid']) }}"> 
     {{ form.csrf_token }} 
     {{ form.upvote }} 
     {{ form.downvote }} 
     </form> 

    </li> 
    {% endfor %} 
</ul> 
関連する問題