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

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

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

Cloud9は、クラウドからのプログラミングが可能になるWebサービス。IDEとしての機能が搭載されており、GitHubやHerokuなど他ツールとの連携も可能です。ブラウザ上で動くため、デバイスに関係なく開発環境を準備できます。

Flask

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

Python

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

Q&A

解決済

1回答

3117閲覧

Flaskでアプリを作成しHerokuにデプロイしたが、sessionが途中で切れてしまう

nokonoko_1203

総合スコア17

Cloud9

Cloud9は、クラウドからのプログラミングが可能になるWebサービス。IDEとしての機能が搭載されており、GitHubやHerokuなど他ツールとの連携も可能です。ブラウザ上で動くため、デバイスに関係なく開発環境を準備できます。

Flask

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

Python

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

0グッド

0クリップ

投稿2018/05/22 11:15

編集2018/05/22 12:17

いつも大変お世話になっております。

表記の件について、AWS Cloud9環境にてFlaskアプリを作成しHerokuデプロイしましたが、sessionが切れたり、リロードしたら戻ってきたりとおかしな挙動をしています。

cloud9でのプレビューでは、問題ないのですが、Herokuにデプロイしたものが同様の動きをせず困っております。

特にログイン後の「edit.html」から「index.html」にリダイレクトするときや、「index.html」で再読み込みをするときに頻発しております。

stokupile.py

1#!/usr/bin/env python 2# coding: utf-8 3 4import sqlite3 5from flask import Flask, render_template, request, redirect, url_for, session, flash 6# from flask.ext.session import Session は廃止されている 7from flask_session import Session 8import os 9 10 11app = Flask(__name__) 12app.secret_key = os.urandom(24) 13SESSION_TYPE = 'filesystem' 14app.config.from_object(__name__) 15sess = Session() 16 17sqlite_path = 'db/stockpile.db' 18users_db_path = 'db/users.db' 19 20 21def get_db_connection(): 22 connection = sqlite3.connect(sqlite_path) 23 connection.row_factory = sqlite3.Row 24 return connection 25 26def get_user_db_connection(): 27 connection = sqlite3.connect(users_db_path) 28 connection.row_factory = sqlite3.Row 29 return connection 30 31 32@app.before_request 33def before_request(): 34 # # 静的ファイルへのアクセスについては、チェック対象としない 35 # if request.path.startswith('/static/'): 36 # return 37 # セッションにusernameが保存されている.つまりログイン済み 38 if session.get("username") == "admin": 39 return 40 # リクエストパスがログインページに関する場合 41 if request.path == '/login': 42 return 43 # ログインされておらず,インデックスに関するリクエストの場合 44 if request.path == '/': 45 return 46 # ログインされておらず,ログインページに関するリクエストでない場合 47 return render_template('index.html') 48 49 50@app.route("/") 51def index(): 52 if session.get("username") == "admin": 53 connection = get_db_connection() 54 cursor = connection.cursor() 55 res = cursor.execute('SELECT * FROM stockpile') 56 return render_template('index.html', stock_list=res.fetchall(), 57 username=session["username"], password=session["password"]) 58 else: 59 connection = get_db_connection() 60 cursor = connection.cursor() 61 res = cursor.execute('SELECT * FROM stockpile') 62 return render_template('index.html', stock_list=res.fetchall()) 63 64 65# 個人認証を行い,正規のアカウントか確認する 66def _is_account_valid(): 67 username = request.form.get('username') 68 password = request.form.get("password") 69 # この例では,ユーザ名にadminが指定されていれば正規のアカウントであるとみなしている 70 # ここで具体的な個人認証処理を行う.認証に成功であればTrueを返すようにする 71 if username == 'admin' and password == 'admin': 72 session["username"] = username 73 return True 74 return False 75 76 77@app.route("/login", methods=["GET", "POST"]) 78def login(): 79 if request.method == 'POST': 80 error = [] 81 username = request.form.get("username", None) 82 password = request.form.get("password", None) 83 if username == "": 84 error.append("名前を入力して下さい") 85 if password == "": 86 error.append("パスワードを入力して下さい") 87 88 if error: 89 stockpile = request.form.to_dict() 90 return render_template("login.html", error_list=error) 91 92 if _is_account_valid(): 93 session["username"] = username 94 session["password"] = password 95 flash('ログインしました', 'info') 96 return redirect(url_for('index')) 97 98 error.append("組み合わせが正しくありません") 99 return render_template("login.html", error_list=error) 100 101 102 elif request.method == 'GET': 103 return render_template("login.html") 104 105 else: 106 return render_template("index.html") 107 108 109@app.route("/logout") 110def logout(): 111 session.pop("username", None) 112 return render_template("index.html") 113 114 115@app.route("/add", methods=["GET", "POST"]) 116def add_stock(): 117 if request.method == "GET": 118 """移動先のテンプレートがformの中で辞書(stockpile)を使ってるから、 119 からのリストを定義しておかないとエラー発生 120 """ 121 stockpile = {} 122 return render_template("edit.html", type="add", stockpile=stockpile) 123 elif _is_account_valid(): 124 connection = get_db_connection() 125 cursor = connection.cursor() 126 error = [] 127 128 if not request.form["name"]: 129 error.append("商品名を入力して下さい") 130 if not request.form["stocknumber"]: 131 error.append("個数を入力して下さい") 132 if not request.form["duedate"]: 133 error.append("賞味期限を入力して下さい") 134 135 if error: 136 #name属性をkey,入力をvalueにした辞書を作成? 137 stockpile = request.form.to_dict() 138 return render_template("edit.html", type="add", stockpile=stockpile, error_list=error) 139 140 cursor.execute("INSERT INTO stockpile(name, stocknumber, duedate, memo) VALUES(?, ?, ?, ?)", 141 (request.form["name"], 142 request.form["stocknumber"], 143 request.form["duedate"], 144 request.form["memo"])) 145 connection.commit() 146 return redirect(url_for('index')) 147 148 149@app.route("/delete/<int:id>") 150def delete(id): 151 connection = get_db_connection() 152 cursor = connection.cursor() 153 cursor.execute("DELETE FROM stockpile WHERE id = ? ", (id,)) 154 connection.commit() 155 return render_template("index.html") 156 157 158@app.route("/edit/<int:id>") 159def edit(id): 160 connection = get_db_connection() 161 cursor = connection.cursor() 162 res = cursor.execute("SELECT * FROM stockpile WHERE id = ? ", (id,)) 163 return render_template("edit.html", type="edit", stockpile=res.fetchone()) 164 165 166@app.route("/update/<int:id>", methods=["POST"]) 167def update_stock(id): 168 error = [] 169 170 if not request.form["name"]: 171 error.append("商品名を入力して下さい") 172 if not request.form["stocknumber"]: 173 error.append("個数を入力して下さい") 174 if not request.form["duedate"]: 175 error.append("期限を入力して下さい") 176 177 if error: 178 stockpile = request.form.to_dict() 179 return render_template("edit.html", type="edit", stockpile=stockpile, error_list=error) 180 181 connection = get_db_connection() 182 cursor = connection.cursor() 183 cursor.execute("UPDATE stockpile set name = ? , stocknumber = ? , duedate = ? , memo = ? where id = ?", 184 (request.form["name"], 185 request.form["stocknumber"], 186 request.form["duedate"], 187 request.form["memo"], 188 id)) 189 connection.commit() 190 return redirect(url_for("index")) 191 192 193if __name__ == '__main__': 194 # app.debug = True # デバッグモード有効化 195 # どこからでもアクセス可能に 196 app.run(host='0.0.0.0', port=8080, threaded=True)

index.html

1{% extends "layout.html" %} 2{% block body %} 3<body> 4 {% for message in get_flashed_messages() %} 5 <div class="alert alert-warning"> 6 {{ message }} 7 </div> 8 {% endfor %} 9 <h1>在庫管理 アプリケーション</h1> 10 {% if session.username == "admin" %} 11 <table> 12 <tr> 13 <th>商品名</th> 14 <th>個数</th> 15 <th>賞味期限</th> 16 <th>メモ</th> 17 <th></th> 18 </tr> 19 {% for v in stock_list %} 20 <tr> 21 <td><a href="{{ url_for('edit', id=v['id'])}}">{{ v['name']}}</a></td> 22 <td>{{ v['stocknumber']}}</td> 23 <td>{{ v['duedate']}}</td> 24 <td>{{ v['memo']}}</td> 25 <td><a href={{ url_for("delete", id=v["id"]) }}>削除</a></td> 26 </tr> 27 {% endfor %} 28 </table> 29 <h3><a href="{{ url_for('add_stock')}}">在庫の追加</a></h3> 30 <h3><a href="{{ url_for('logout')}}">ログアウト</a></h3> 31 {% else %} 32 <h3><a href="{{ url_for('login')}}">ログイン</a></h3> 33 {% endif %} 34</body> 35{% endblock %}

edit.html

1{% extends "layout.html" %} 2{% block body %} 3<body> 4 5 <h1>在庫を編集する</h1> 6 7 <form method="post" action="{% if type == "add" %}{{ url_for('add_stock') }}{% else %}{{ url_for('update_stock', id=stockpile["id"]) }}{% endif %}"> 8 {% if error_list %} 9 <ul> 10 {% for v in error_list %} 11 <li>{{ v }}</li> 12 {% endfor %} 13 </ul> 14 {% endif %} 15 <p>商品名<br/><input type="text" name="name" value="{{ stockpile['name'] }}"/></p> 16 <p>在庫数<br/><input type="int" name="stocknumber" value="{{ stockpile['stocknumber'] }}"/></p> 17 <p>期限<br/><input type="text" name="duedate" value="{{ stockpile['duedate'] }}"/></p> 18 <p>メモ<br/><input type="text" name="memo" value="{{ stockpile['memo'] }}" size="60"/></p> 19 {% if type == "add" %} 20 <button type="submit">在庫を追加</button> 21 {% else %} 22 <button type="submit">在庫を更新</button> 23 {% endif %} 24 </form> 25 <br/> 26 <a href="{{ url_for('index')}}">トップに戻る</a> 27</body> 28{% endblock %}

調べてみた限りではredisを利用してsessionをデータベースに保存するのがいいようなことはわかったのですが、Railsでのやり方や、英語のドキュメントしか見当たらず、理解することができませんでした。

ご教示いただけると幸いです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

以前Herokuでflaskを動かしたときsecret_keyがランダムだと正常に動作しなかったので多分それじゃないかと。違ってたらすみません。

投稿2018/05/23 10:15

bluevinyl

総合スコア129

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

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

nokonoko_1203

2018/05/23 11:37

解決いたしました!!! 本当にありがとうございました!
namipapa

2022/05/05 08:21

最近、FlaskとHerokuをはじめたものです。ローカルではちゃんと動くのに、Herokuでリリースするとうまくいかない。うまくいってないところがセッションのところみたいということで、ここにたどり着きました。おかげさまで解決しました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問