前提・実現したいこと
Flaskを用いて評価フォームを準備し、入力されたデータをデータベースにあげるという一連の関数を作成中です。
同じ型のFlaskFormをfor文で作成し、リストとしてまとめた物を別のリストとzip関数で辞書型にまとめ、render_template時に渡し、HTML上のテンプレートタグにて展開することができました。
しかし、submitされた際に入力された内容をそれぞれデータベース上に上げようとすると、データがすべてリストにおける一つ目のFlaskFormで入力されたものになってしまいます。
評価項目数に応じてHTMLに渡すFlaskFormの数を変えたいためfor文にて作成しています。
submitフォームは別のFlaskFormにて定義しています。
- FlaskFormの定義
- render_template時にFormを渡す
- validate関数にエラーがない場合はデータベースにあげる
"3."のデータベースにデータをあげることはできますが、データが入力されたものと一致していない。
テストコード
ファイル構造
.
├── app.py
└── templates
---├── evaluate.html
---└── evaluated.html
app.py
python
1from flask import Flask, render_template, url_for, redirect 2from wtforms.validators import DataRequired 3from flask_wtf import FlaskForm 4from wtforms import StringField, PasswordField, SubmitField, BooleanField, SelectField, TextAreaField, IntegerField 5 6app = Flask(__name__) 7app.config['SECRET_KEY'] = '1234567890' 8 9 10class Submit(FlaskForm): 11 year = IntegerField('評価年', validators=[DataRequired()], default = 2020) 12 submit = SubmitField('登録') 13 14class Evaluation(FlaskForm): 15 value = StringField('評価値', validators=[DataRequired()]) 16 message = TextAreaField('コメント', render_kw={'rows': 4}) 17 18@app.route('/', methods=['GET','POST']) 19def home(): 20 21 form = Submit() 22 23 list_of_form = [] 24 list_of_function_name = ['Column1', 'Column2', 'Column3'] 25 26 for a in range(len(list_of_function_name)): 27 list_of_form.append(Evaluation()) 28 print(list_of_form) 29 30 list_of_form_dictionary = dict(zip(list_of_function_name, list_of_form)) 31 32 if form.validate_on_submit(): 33 for a in range(len(list_of_form)): 34 print(print(list_of_form[a].value.data)) 35 print(print(list_of_form[a].message.data)) 36 37 return render_template('evaluated.html', title = '評価値', list_of_form = list_of_form ) 38 39 return render_template('evaluate.html', title = 'テスト', form = form, evaluation_list = list_of_form_dictionary) 40
evaluate.html
HTML
1<!DOCTYPE html> 2<html> 3<head> 4 <!-- Required meta tags --> 5 <meta charset="utf-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> 7 8 <!-- Bootstrap CSS --> 9 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" crossorigin="anonymous"> 10 11 {% if title %} 12 <title>{{ title }}</title> 13 {% else %} 14 <title>HOME</title> 15 {% endif %} 16</head> 17<body> 18 <header class="site-header"> 19 </header> 20 <main role="main" class="container"> 21 <div class="row"> 22 <div class="col-md-12"> 23 <div class="container"> 24 <form method="POST" action=""> 25 {{ form.hidden_tag() }} 26 <fieldset class="form-group"> 27 <legend class="border-bottom mb-4">評価</legend> 28 <div class="form-group"> 29 {{ form.year.label(class="form-control-label") }} 30 {% if form.year.errors %} 31 {{ form.year(class="form-control form-control-lg is-invalid") }} 32 <div class="invalid-feedback"> 33 {% for error in form.year.errors %} 34 <span>エラー</span> 35 {% endfor %} 36 </div> 37 {% else %} 38 {{ form.year(class="form-control form-control-lg") }} 39 {% endif %} 40 </div> 41 42 {% for name, evaluation_form in evaluation_list.items() %} 43 <h3>{{ name[5:] }}</h3> 44 <div class="form-group"> 45 {{ evaluation_form }} 46 {{ evaluation_form.value.label(class="form-control-label") }} 47 {% if evaluation_form.value.errors %} 48 {{ evaluation_form.value(class="form-control form-control-lg is-invalid") }} 49 <div class="invalid-feedback"> 50 {% for error in evaluation_form.value.errors %} 51 <span>エラー</span> 52 {% endfor %} 53 </div> 54 {% else %} 55 {{ evaluation_form.value(class="form-control form-control-lg") }} 56 {% endif %} 57 </div> 58 <div class="form-group"> 59 {{ evaluation_form.message.label(class="form-control-label") }} 60 {% if evaluation_form.message.errors %} 61 {{ evaluation_form.message(class="form-control form-control-lg is-invalid") }} 62 <div class="invalid-feedback"> 63 {% for error in evaluation_form.message.errors %} 64 <span>エラー</span> 65 {% endfor %} 66 </div> 67 {% else %} 68 {{ evaluation_form.message(class="form-control form-control-lg") }} 69 {% endif %} 70 </div> 71 {% endfor %} 72 73 74 </fieldset> 75 76 <div class="form-group"> 77 {{ form.submit(class="btn btn-outline-info") }} 78 </div> 79 </form> 80 </div> 81 </div> 82 </div> 83 </main> 84</body> 85</html> 86
evaluated.html
HTML
1<!DOCTYPE html> 2<html> 3<head> 4 <!-- Required meta tags --> 5 <meta charset="utf-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> 7 8 <!-- Bootstrap CSS --> 9 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" crossorigin="anonymous"> 10 11 {% if title %} 12 <title>{{ title }}</title> 13 {% else %} 14 <title>HOME</title> 15 {% endif %} 16</head> 17<body> 18 <header class="site-header"> 19 </header> 20 <main role="main" class="container"> 21 <div class="row"> 22 <div class="col-md-12"> 23 <div class="container"> 24 {{ list_of_form }} 25 {% for written in list_of_form %} 26 <h3>{{ written.value.data }}</h3> 27 <h4>{{ written.message.data }}</h4> 28 <br> 29 {% endfor %} 30 </div> 31 </div> 32 </div> 33 </main> 34</body> 35</html> 36
試したこと
for文によって作成したFlaskFormの格納アドレスとHTML側に渡された後での各FlaskFormの格納アドレスが一致しているか。
結果、同じアドレスに保存されているFormを用いている。
HTMLコード4行目
{{ evaluation_form }}
にて試験的に出力された値と比較
補足情報(FW/ツールのバージョンなど)
Flask==1.1.1
Flask-WTF==0.14.2
WTForms==2.2.1
Python 3.7.4
回答1件
あなたの回答
tips
プレビュー