いつも大変お世話になっております。
表記の件について、AWS Cloud9環境にてFlaskアプリを作成しHerokuデプロイしましたが、sessionが切れたり、リロードしたら戻ってきたりとおかしな挙動をしています。
cloud9でのプレビューでは、問題ないのですが、Herokuにデプロイしたものが同様の動きをせず困っております。
特にログイン後の「edit.html」から「index.html」にリダイレクトするときや、「index.html」で再読み込みをするときに頻発しております。
stokupile.py
#!/usr/bin/env python # coding: utf-8 import sqlite3 from flask import Flask, render_template, request, redirect, url_for, session, flash # from flask.ext.session import Session は廃止されている from flask_session import Session import os app = Flask(__name__) app.secret_key = os.urandom(24) SESSION_TYPE = 'filesystem' app.config.from_object(__name__) sess = Session() sqlite_path = 'db/stockpile.db' users_db_path = 'db/users.db' def get_db_connection(): connection = sqlite3.connect(sqlite_path) connection.row_factory = sqlite3.Row return connection def get_user_db_connection(): connection = sqlite3.connect(users_db_path) connection.row_factory = sqlite3.Row return connection @app.before_request def before_request(): # # 静的ファイルへのアクセスについては、チェック対象としない # if request.path.startswith('/static/'): # return # セッションにusernameが保存されている.つまりログイン済み if session.get("username") == "admin": return # リクエストパスがログインページに関する場合 if request.path == '/login': return # ログインされておらず,インデックスに関するリクエストの場合 if request.path == '/': return # ログインされておらず,ログインページに関するリクエストでない場合 return render_template('index.html') @app.route("/") def index(): if session.get("username") == "admin": connection = get_db_connection() cursor = connection.cursor() res = cursor.execute('SELECT * FROM stockpile') return render_template('index.html', stock_list=res.fetchall(), username=session["username"], password=session["password"]) else: connection = get_db_connection() cursor = connection.cursor() res = cursor.execute('SELECT * FROM stockpile') return render_template('index.html', stock_list=res.fetchall()) # 個人認証を行い,正規のアカウントか確認する def _is_account_valid(): username = request.form.get('username') password = request.form.get("password") # この例では,ユーザ名にadminが指定されていれば正規のアカウントであるとみなしている # ここで具体的な個人認証処理を行う.認証に成功であればTrueを返すようにする if username == 'admin' and password == 'admin': session["username"] = username return True return False @app.route("/login", methods=["GET", "POST"]) def login(): if request.method == 'POST': error = [] username = request.form.get("username", None) password = request.form.get("password", None) if username == "": error.append("名前を入力して下さい") if password == "": error.append("パスワードを入力して下さい") if error: stockpile = request.form.to_dict() return render_template("login.html", error_list=error) if _is_account_valid(): session["username"] = username session["password"] = password flash('ログインしました', 'info') return redirect(url_for('index')) error.append("組み合わせが正しくありません") return render_template("login.html", error_list=error) elif request.method == 'GET': return render_template("login.html") else: return render_template("index.html") @app.route("/logout") def logout(): session.pop("username", None) return render_template("index.html") @app.route("/add", methods=["GET", "POST"]) def add_stock(): if request.method == "GET": """移動先のテンプレートがformの中で辞書(stockpile)を使ってるから、 からのリストを定義しておかないとエラー発生 """ stockpile = {} return render_template("edit.html", type="add", stockpile=stockpile) elif _is_account_valid(): connection = get_db_connection() cursor = connection.cursor() error = [] if not request.form["name"]: error.append("商品名を入力して下さい") if not request.form["stocknumber"]: error.append("個数を入力して下さい") if not request.form["duedate"]: error.append("賞味期限を入力して下さい") if error: #name属性をkey,入力をvalueにした辞書を作成? stockpile = request.form.to_dict() return render_template("edit.html", type="add", stockpile=stockpile, error_list=error) cursor.execute("INSERT INTO stockpile(name, stocknumber, duedate, memo) VALUES(?, ?, ?, ?)", (request.form["name"], request.form["stocknumber"], request.form["duedate"], request.form["memo"])) connection.commit() return redirect(url_for('index')) @app.route("/delete/<int:id>") def delete(id): connection = get_db_connection() cursor = connection.cursor() cursor.execute("DELETE FROM stockpile WHERE id = ? ", (id,)) connection.commit() return render_template("index.html") @app.route("/edit/<int:id>") def edit(id): connection = get_db_connection() cursor = connection.cursor() res = cursor.execute("SELECT * FROM stockpile WHERE id = ? ", (id,)) return render_template("edit.html", type="edit", stockpile=res.fetchone()) @app.route("/update/<int:id>", methods=["POST"]) def update_stock(id): error = [] if not request.form["name"]: error.append("商品名を入力して下さい") if not request.form["stocknumber"]: error.append("個数を入力して下さい") if not request.form["duedate"]: error.append("期限を入力して下さい") if error: stockpile = request.form.to_dict() return render_template("edit.html", type="edit", stockpile=stockpile, error_list=error) connection = get_db_connection() cursor = connection.cursor() cursor.execute("UPDATE stockpile set name = ? , stocknumber = ? , duedate = ? , memo = ? where id = ?", (request.form["name"], request.form["stocknumber"], request.form["duedate"], request.form["memo"], id)) connection.commit() return redirect(url_for("index")) if __name__ == '__main__': # app.debug = True # デバッグモード有効化 # どこからでもアクセス可能に app.run(host='0.0.0.0', port=8080, threaded=True)
index.html
{% extends "layout.html" %} {% block body %} <body> {% for message in get_flashed_messages() %} <div class="alert alert-warning"> {{ message }} </div> {% endfor %} <h1>在庫管理 アプリケーション</h1> {% if session.username == "admin" %} <table> <tr> <th>商品名</th> <th>個数</th> <th>賞味期限</th> <th>メモ</th> <th></th> </tr> {% for v in stock_list %} <tr> <td><a href="{{ url_for('edit', id=v['id'])}}">{{ v['name']}}</a></td> <td>{{ v['stocknumber']}}</td> <td>{{ v['duedate']}}</td> <td>{{ v['memo']}}</td> <td><a href={{ url_for("delete", id=v["id"]) }}>削除</a></td> </tr> {% endfor %} </table> <h3><a href="{{ url_for('add_stock')}}">在庫の追加</a></h3> <h3><a href="{{ url_for('logout')}}">ログアウト</a></h3> {% else %} <h3><a href="{{ url_for('login')}}">ログイン</a></h3> {% endif %} </body> {% endblock %}
edit.html
{% extends "layout.html" %} {% block body %} <body> <h1>在庫を編集する</h1> <form method="post" action="{% if type == "add" %}{{ url_for('add_stock') }}{% else %}{{ url_for('update_stock', id=stockpile["id"]) }}{% endif %}"> {% if error_list %} <ul> {% for v in error_list %} <li>{{ v }}</li> {% endfor %} </ul> {% endif %} <p>商品名<br/><input type="text" name="name" value="{{ stockpile['name'] }}"/></p> <p>在庫数<br/><input type="int" name="stocknumber" value="{{ stockpile['stocknumber'] }}"/></p> <p>期限<br/><input type="text" name="duedate" value="{{ stockpile['duedate'] }}"/></p> <p>メモ<br/><input type="text" name="memo" value="{{ stockpile['memo'] }}" size="60"/></p> {% if type == "add" %} <button type="submit">在庫を追加</button> {% else %} <button type="submit">在庫を更新</button> {% endif %} </form> <br/> <a href="{{ url_for('index')}}">トップに戻る</a> </body> {% endblock %}
調べてみた限りではredisを利用してsessionをデータベースに保存するのがいいようなことはわかったのですが、Railsでのやり方や、英語のドキュメントしか見当たらず、理解することができませんでした。
ご教示いただけると幸いです。
まだ回答がついていません
会員登録して回答してみよう