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

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

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

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

Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2431閲覧

Python,FlaskのSessionについて

holmirr707

総合スコア10

Flask

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

Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/09/10 07:23

前提・実現したいこと

Python,FlaskでTo doリストを作っている際に、Sessionについて分からなくなったので質問します。
ソースコードを簡単に説明すると、/todoでクライアントからの入力をPOSTで受け取り/taskに送ります。
/taskでsession["todo"]が参照しているリストに、POSTで受け取った値を追加して、もう一度/todoにリダイレクトします。

現在のソースコートだとtask()でリストを更新しても、todo()にリダイレクトするとリストが空に戻ってしまいます。
task()でコメントアウトしているsession["todo"]=temp_listがあれば、すべて上手く行くのですが、なぜ必要なのか分かりません。

sessionをglobalな辞書くらいにしか思っていなかったのですが、それが違うのだと分かりました。
sessionの動態を教えていただけたら嬉しいです。

発生している問題・エラーメッセージ

task()のコメントアウトしている行(session["todo"]=temp_list)があれば、redirect先であるtodo()でもsession["todo"]の値が使えるが、その行がないと、session["todo"]が更新されず、空のリストのまま。

該当のソースコード

@app.route("/todo") def todo(): if session.get("todo", None) is None: print("sessionのtodoリストを作成します") session["todo"] = [] return render_template("todo.html", output_list=session["todo"]) @app.route("/task", methods=["GET", "POST"]) def task(): if request.method == "POST": temp_list = session["todo"] temp_list.append(request.form["task"]) #session["todo"] = temp_list return redirect(url_for("todo"))

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

現在のソースコートだとtask()でリストを更新しても、todo()にリダイレクトするとリストが空に戻ってしまいます。

何か勘違いがあるのだと思います。
holmirr707さんのコードで、sessionに値を追加しているのは以下の2行です。

python

1 session["todo"] = [] 2 #session["todo"] = temp_list

上はsession["todo"]に空リストを代入にします。
空リストを代入する条件は以下です。

  1. /todoを呼び出す。(初回のみ)
  2. /taskを呼び出す。(初回のみ)

どちらのURLを呼んでも、初回だけsession["todo"]に空リストを代入してくれます。
そのあとdef todo()return render_template()によりtodo.htmlが呼ばれます。

下はコメントアウトされているので現状実行されません。
実行されないので、session["todo"]に値を入力しているところは、上だけであり、他に値を追加している部分がないことがわかります。

task()でコメントアウトしているsession["todo"]=temp_listがあれば、すべて上手く行くのですが、なぜ必要なのか分かりません。
sessionをglobalな辞書くらいにしか思っていなかったのですが、それが違うのだと分かりました。
sessionの動態を教えていただけたら嬉しいです。

上の文章を読んでいただけばわかると思いますが、現状のコードだとsession["todo"]は空のリスト以外が入りません。
よって、「リストを更新」はされていません。

python

1 temp_list = session["todo"] 2 temp_list.append(request.form["task"])

この部分が「リストを更新」とおっしゃっているのだと思いますが、更新しているのはtmp_listです。
このtmp_listdef task()temp_list = session["todo"]以降の行で使えますが、当然ながらdef todo()では使えません
return redirect(url_for("todo"))が実行されたところでなくなってしまうので、その前にsession["todo"] = temp_listで代入してください。

投稿2020/09/10 08:51

FiroProchainezo

総合スコア2424

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

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

holmirr707

2020/09/10 09:20

詳しい説明ありがとうございます。 何度も申し訳ありませんが、1つだけお聞きしたいです。 session["todo"]が参照するのは「A」というリストオブジェクトだとすると、 temp_list = session["todo"]とした時点で、temp_listも同じく「A」を参照することになるので、temp_listでappend()を行えば、「A」が変更され、それを参照しているsession["todo"]も変わるという認識だったのですが、その考えが根本から違うということですよね。 もし、sessionが完全にdictだとしたら(あり得ませんが)、上記のような振る舞いになると思うんですが、やはりsessionとdictは違うということでしょうか。
FiroProchainezo

2020/09/11 01:05

確かにdictを別の変数に代入して、代入先を変更しても代入元が変更されますね。 sessionはcookieから取得してるはずなので、完全にdictと同じようには使えないです。 あくまで、「sessionをdictの様な操作で取得/変更しているだけ」です。 そのため、localでの変更はlocalだけ、sessionを変えたいならsessinを変更してください。
holmirr707

2020/09/11 07:58

ご丁寧にありがとうございます。 おかげですっきりしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問