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

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

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

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

Flask

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

Python

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

解決済

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

nokonoko_1203
nokonoko_1203

総合スコア17

Cloud9

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

Flask

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

Python

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

1回答

0評価

0クリップ

2425閲覧

投稿2018/05/22 11:15

編集2022/05/05 17:21

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

表記の件について、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でのやり方や、英語のドキュメントしか見当たらず、理解することができませんでした。

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

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Cloud9

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

Flask

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

Python

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