質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Jinja2

Jinja2は、Python用のテンプレートエンジンです。テンプレートファイルの読込や文字列の埋込、分岐/ループの制御文のサポートなどの機能を持ちます。HTMLやXML生成によく使用されますが、どのような文書でも生成することが可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

546閲覧

flask-wtfで、value属性を使いたい

gragonfly0808

総合スコア14

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Jinja2

Jinja2は、Python用のテンプレートエンジンです。テンプレートファイルの読込や文字列の埋込、分岐/ループの制御文のサポートなどの機能を持ちます。HTMLやXML生成によく使用されますが、どのような文書でも生成することが可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2023/02/15 09:59

実現したいこと

flaskでwtf-formを用いて、フォームを作成しています。
現在、ユーザー情報の更新を行うルーティングを作成しています。ユーザー情報の更新を行うページで、jinjaテンプレートを用いてhtmlのinputタグにレンダリングされる部分にvalue属性を付与したいと考えています。以下、ダラダラと質問内容の詳細を書いていますが、結論としてはwtf-formでvalue属性を使う方法を教えていただきたいです。よろしくお願いします。

前提

flask-wtfを使わない書き方であれば、目的の表示を行うことができます。以下に、htmlタグで直接書いたパターン(成功しているパターン)とflask-wtfで書いたパターン(失敗しているパターン)を示します。

[ファイル構成]
(該当ファイルのみ、成功しているパターンと失敗しているパターンのどちらもファイル構造は同じです。)

C:. │ app.py │ └─templates  admin-userupdate.html

成功しているパターン

python

1###該当する部分のコードのみ載せています。### 2 3#フォームクラス 4class RegisterForm(FlaskForm): 5 username = StringField('名前') 6 email = EmailField('メールアドレス') 7 password = PasswordField('パスワード') 8 calender = StringField('カレンダーのタグ') 9 room = URLField('ミーティングのリンク') 10 submit = SubmitField('登録') 11 12#ユーザーテーブル 13class User(UserMixin, db.Model): 14 __tablename__ = 'User' 15 id = db.Column(db.Integer, primary_key=True) 16 username = db.Column(db.String(100), nullable=False) 17 email = db.Column(db.String(100), nullable=False, unique=True) 18 password = db.Column(db.String(100), nullable=False) 19 calender = db.Column(db.String(1000), nullable=False) 20 room = db.Column(db.String(1000), nullable=False) 21 def __init__(self, username, email, password, calender, room): 22 self.username = username 23 self.email = email 24 self.password = password 25 self.calender = calender 26 self.room = room 27 28with app.app_context(): 29 db.create_all() 30 31#該当のルーティングのみ載せています。 32@app.route('/<int:id>/update', methods=['GET', 'POST']) 33def adminuserupdate(id): 34 if 'login' in session: 35 #特定のid番号の情報を取得 36 user = User.query.get(id) 37 if request.method == 'POST': 38 #上書き 39 user.username = request.form.get('username') 40 user.email = request.form.get('email') 41 user.calender = request.form.get('calender') 42 user.room = request.form.get('room') 43 db.session.commit() 44 return redirect('/admin') 45 else: 46 return render_template('admin-userupdate.html', user=user)

html

1#該当箇所のみ載せています。 2<h1>編集画面</h1> 3<form method="POST"> 4 <label for="usrename">ユーザー名</label> 5 <input type="text" name="username" value={{ user.username }}> 6 <label for="email">Email</label> 7 <input type="email" name="email" value={{ user.email }}> 8 <label for="calender">カレンダーのタグ</label> 9 <input type="text" name="calender" value={{ user.calender }}> 10 <label for="room">ルームのURL</label> 11 <input type="url" name="room" value={{ user.room }}> 12 <input type="submit" value="更新"> 13</form>

失敗しているパターン

python

1###該当する部分のコードのみ載せています。### 2 3#フォームクラス 4class RegisterForm(FlaskForm): 5 username = StringField('名前') 6 email = EmailField('メールアドレス') 7 password = PasswordField('パスワード') 8 calender = StringField('カレンダーのタグ') 9 room = URLField('ミーティングのリンク') 10 submit = SubmitField('登録') 11 12#ユーザーテーブル 13class User(UserMixin, db.Model): 14 __tablename__ = 'User' 15 id = db.Column(db.Integer, primary_key=True) 16 username = db.Column(db.String(100), nullable=False) 17 email = db.Column(db.String(100), nullable=False, unique=True) 18 password = db.Column(db.String(100), nullable=False) 19 calender = db.Column(db.String(1000), nullable=False) 20 room = db.Column(db.String(1000), nullable=False) 21 def __init__(self, username, email, password, calender, room): 22 self.username = username 23 self.email = email 24 self.password = password 25 self.calender = calender 26 self.room = room 27 28with app.app_context(): 29 db.create_all() 30 31#該当のルーティングのみ載せています。 32@app.route('/<int:id>/update', methods=['GET', 'POST']) 33def adminuserupdate(id): 34 if 'login' in session: 35 #特定のid番号の情報を取得 36 user = User.query.get(id) 37 form = RegisterForm() 38 # if request.method == 'POST': 39 if form.validate_on_submit(): 40 #上書き 41 user.username = form.username.data 42 user.email = form.email.data 43 user.calender = form.calender.data 44 user.room = form.room.data 45 db.session.commit() 46 return redirect('/admin') 47 else: 48 return render_template('admin-userupdate.html', form=form)

html

1#当該箇所のみ載せています。 2#私の書き方は、明らかに間違っているので正しい書き方を教えてください。 3#よろしくお願いします。 4<h1>編集画面</h1> 5<form method="POST"> 6 <!-- <label for="usrename">ユーザー名</label> 7 <input type="text" name="username" value={{ user.username }}> 8 <label for="email">Email</label> 9 <input type="email" name="email" value={{ user.email }}> 10 <label for="calender">カレンダーのタグ</label> 11 <input type="text" name="calender" value={{ user.calender }}> 12 <label for="room">ルームのURL</label> 13 <input type="url" name="room" value={{ user.room }}> 14 <input type="submit" value="更新"> --> 15 {{ form.csrf_token }} 16 {{ form.username(value={{ user.username }}) }} 17 <br> 18 {{ form.email(value={{ user.email }}) }} 19 <br> 20 {{ form.calender(value={{ user.calender }}) }} 21 <br> 22 {{ form.room(value={{ user.room }}) }} 23 {{ form.submit }} 24</form>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Flask-WTFでフォームを作って、Update処理をしたい。
Updateなので、既存のユーザIDなどでDBの検索を実施し、既存の情報をFormに反映した。
みたいなことですかね?

if 'login' in session:部分がよく分かりませんが、ログインしてたら変更可能とかなんですかね?

とりあえず、以下でDBのデータをFormに反映できます。

python

1form = RegisterForm() 2form.username.data = '検索した結果の値' 3# これを、render_templateの第2引数以降で渡し、HTMLに反映する。

これで分かりますか?

なんとなく分からない気がするのでもう少し詳しく書きます。

html側は以下の様な感じです。

html

1<form method="POST"> 2 {{ form.csrf_token }} 3 {{ form.username.label }} 4 {{ form.username() }} 5 <!-- 略 --> 6 <input type="submit" value="更新" id="submit"> 7</form>

データは、Python側で書き換え、HTML(Jinja2)側では書きません。
勝手にHTML(Form)を作ってくれるのはFlask-WTFの良いところです。

いかがでしょうか?

分からないかもしれないので、さらにもうちょっと書きます。

まず、ユーザ情報更新画面の画面遷移について考える必要があります。
このページは@app.route('/<int:id>/update', methods=['GET', 'POST'])とある通り、idが渡される前提のページで、idが間違っていることは今のところ検討されていませんので、正しいidが入っていると言う前提で書きます。
(idが無い場合とかも、この後で検討ください)

例えば/1/updateみたいに呼ばれます。
1がユーザIDです。
この時のメソッドはGETだと思いますので、「GETメソッドで、ID1の変更画面」が表示されるはずです。
当然、ログインされているページです。
なので、まず、「ログインされていて」「GET」メソッドの場合は、「指定されているIDを検索して、Formに反映した」ページを返す必要があります。
これが最初の画面です。
既に登録済みのユーザデータを反映したフォームを表示する画面ですね。

次に、更新処理です。
Formでsubmit(更新ボタン)を押すと、「POST」処理が走ります。
actionは指定されていないので、同じURLに対して「POST」メソッドでアクセスされます。
つまり/1/updateです。ここの「POST」します。
なので、「ログインされていて」「POST」メソッドの場合は、「更新処理を実施」します。(値が正しいかの確認はしてください。バリデーションが何も書かれていないので、csrtトークンが正しければ通る気がしますので。)

つまり、大まかに書くと以下の様になります。(すみません、日本語で書きます。)

py

1if # ログインしてるか? 2 # idは正しいはずなので、DBから取得する 3 user = # idで検索してdbから取得 4 form = RegisterForm() 5 6 if # methodはPOSTか?: 7 # POSTということは更新処理 8 username = # form.username.data 9 # 他にも必要であれば反映する。 10 db.session.commit() 11 return redirect("更新が終わったので、他のページに移動。同じページに移動しても良い。") 12 13 else # GETアクセスの場合: 14 # GETということは、検索した結果のフォームを表示する。 15 form.username.data = user.username 16 # 他のも必要があれば反映する。 17 return render_template('htmlの名前', form=form) 18 19return redirect("ログインしてないので、ログイン画面などに戻す") 20

更新処理時に、データが足りないとか変なデータが入っている場合には、else側処理と同じようにformに入力されたデータを反映して表示します。

form.validate_on_submit()は、上記が出来たら検討しましょう。
結局必要ですが、なんか正しいのに動かない、になるので最初は無しのコードが良いと思います。(CSRFがくせ者なので)

これでどうでしょうか?
そもそも回答が間違っていたらご指摘ください。
わからない事がある場合も追加でコメントお願いします。

投稿2023/02/17 13:05

FiroProchainezo

総合スコア2402

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gragonfly0808

2023/02/18 01:23

ご教授していただきありがとうございました。 無事、Flask-WTFでUpdate処理を行うことができました。 今まで、POST処理のみで解決できるものだと思い込んでしまっていたのが問題でした。 私の質問の仕方が下手で、回答される際に戸惑いを与えてしまい、申し訳ありませんでした。 最後に、解決した際のコードを載せておきます。 ```html #cssを充てるために構造が質問時と異なりますがご了承ください。 <div class="body-container"> <div class="h1-container"> <h1 class="ja"></h1> </div> <div class="box_con"> <form method="POST"> {{ form.csrf_token }} <table class="formTable"> <tr> <th class="ja">生徒情報の更新</th> <td>{{ form.username(size="30") }}</td> </tr> <tr> <th class="ja">メールアドレス</th> <td>{{ form.email(size="30") }}</td> </tr> <tr> <th class="ja">カレンダー</th> <td>{{ form.calender(size="30") }}</td> </tr> <tr> <th class="ja">Talky URL</th> <td>{{ form.room(size="30") }}</td> </tr> </table> <p class="btn"> <span>{{ form.submit(class="ja login") }}</span> </p> </form> </div> </div> ``` ```python #該当のルーティングのみ載せています。 @app.route('/<int:id>/update', methods=['GET', 'POST']) def adminuserupdate(id): if 'login' in session: #特定のid番号の情報を取得 form = UpdateForm() user = User.query.get(id) if request.method == 'POST': #上書き user.username = form.username.data user.email = form.email.data user.calender = form.calender.data user.room = form.room.data db.session.commit() return redirect('/admin') else: form.username.data = user.username form.email.data = user.email form.calender.data = user.calender form.room.data = user.room return render_template('admin-userupdate.html', form=form) ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問