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

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

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

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

Python 3.x

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

Q&A

解決済

1回答

2323閲覧

【Flask】Blueprintで分けられた所だけにLoginManagerを機能をさせたい

jyansinkai

総合スコア66

Flask

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

Python 3.x

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

0グッド

1クリップ

投稿2022/03/17 04:53

編集2022/03/25 16:31

いつもお世話になっております。
これまでLoginManagerでログイン、ログアウト機能を持たせていたサイトをBlueprintで複数に分けました。その一部だけにログイン・ログアウト機能をつけたいのです。
server.pyの位置にフォルダA、B、Cを設け、フォルダC以下にログイン機能を持たせようと、以下のようなコードを作成しました。

server.py

1from flask import Flask, render_template, url_for, request, redirect 2 3# 分割したモジュールをインポート 4from A.A import A_app 5from B.B import B_app 6from C.C import C_app 7 8# Flask使用準備 9app = Flask(__name__) 10 11# 分割先のBlueprintを登録 12app.register_blueprint(A_app, url_prefix='/A') 13app.register_blueprint(B_app, url_prefix='/B') 14app.register_blueprint(C_app, url_prefix='/C') 15 16if __name__ == '__main__': 17 app.run(debug=True) 18

C.py

1import sqlite3 2from flask import Flask, render_template, request,Response, abort, redirect, session, Blueprint 3from flask_login import LoginManager, login_user, logout_user, login_required, UserMixin 4from collections import defaultdict 5 6# Blueprintオブジェクトを生成 7C_app = Blueprint('C', __name__,template_folder='templates', static_folder='static') 8 9# ログインマネージャー準備 10login_manager = LoginManager() 11login_manager.init_app(C_app) 12C_app.config['SECRET_KEY'] = "secret" 13 14#ログイン情報をデータベースから引き出す処理(中略) 15 16@login_manager.user_loader 17def load_user(user_id): 18 return users.get(int(user_id)) 19 20@C_app.route('/', methods=["GET", "POST"]) 21def login(): 22 if(request.method == "POST"): 23 # ユーザーチェック 24 # ユーザーが存在した場合はログイン 25 # ユーザーが存在しない場合はエラー 26 #GETならログインページを表示 27 28@C_app.route('/home') 29@login_required 30#home画面へ 31 32@C.route('/logout') 33@login_required 34def logout(): 35#ログアウト処理

localhostで動かしてみました所、以下のようなエラーが出ました。

AttributeError: 'Flask' object has no attribute 'login_manager'

フォルダA、Bの内容は表示されますが、フォルダCだけ上記のエラーとなります。
LoginManagerを準備するタイミングがまずいのではと様々な位置へ移動し実行してみましたがエラーは直りませんでした。
どの部分が間違っており、どのようにすれば意図した機能とすることができるか、何卒ご教授下さいます様お願い申し上げます。

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

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

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

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

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

guest

回答1

0

ベストアンサー

まず、エラーは端折らず全文表示してください。

回答ですが、LoginManagerをserver.pyで作成すれば良いと思います。

C.pyの方では、

python

1from flask_login import login_required

の様にすれば使用できます。
同様にimportすればlogin_userlogout_user, current_userも使用可能だったはずです。

それから、たぶんですが、SECRET_KEYもappの方で書くべきもののはずです。
blueprintの方でSECRET_KEYを指定しているソースを見たことが無いので、やろうとしたこともないのですが、もし動作がおかしかったら気にしてみてください。

追記(2022/03/25 15:41)

cannot import name 'C_app' from 'C.C'が解決されないということですね。

その前に書いていただいたエラーメッセージの以下部分より

text

1 File "C:\C\C.py", line 8, in <module> 2 from server import login_manager

そのそも実行できないコードを書いている可能性が高いです。
この login_manager は 以下で定義した login_manager であると思うので、インポートできないと怒られているのだと思います。

python

1app = Flask(__name__) 2login_manager.init_app(app)

C.pyではlogin_managerのimportは不要のはずです。
C.pyの該当行を削除して実行ください。

C.pyでは login_manager を作る必要は無く、回答上の方に書いた、以下を記載するだけで利用可能のはずです。

python

1from flask_login import login_required

login_requiredは以下のように使用します。

python

1C_app = Blueprint(省略) 2 3@C_app.route('/') 4@login_required 5def index() 6 # 処理 7

こうすると、 def index() はログイン済みユーザしかアクセスできなくなります。
ログイン処理やログアウト処理、遷移処理は別途記載する必要があります。

投稿2022/03/23 05:39

編集2022/03/25 06:54
FiroProchainezo

総合スコア2387

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

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

jyansinkai

2022/03/25 02:40

ご指導、誠に有難うございます。 ご教示のございました通り、以下のように修正しました。 ① C.pyから # ログインマネージャー準備 login_manager = LoginManager() login_manager.init_app(C_app) C_app.config['SECRET_KEY'] = "secret" の部分を切り取り、server.pyにペーストしました。 ② C.pyに from flask_login import login_required を付け足しました。 ③ server.pyに from flask_login import LoginManager を付け足しました。 上記①②③を修正し実行した所、以下のようなエラーが出ました。 Traceback (most recent call last): File "SERVER.PY", line 10, in <module> from C.C import C_app File "C:\C\C.py", line 8, in <module> from server import login_manager File "C:\server.py", line 10, in <module> from C.C import C_app ImportError: cannot import name 'C_app' from 'C.C' (C:\C\C.py) C_appがimportできないのは、上記①②③に過不足があるのでしょうか?
FiroProchainezo

2022/03/25 05:07

login_manager.init_appの引数に与えるのはblueprintじゃなくて、appです。 C_appではなく、appを与えて下さい。 ---code app = Flask(__name__) login_manager.init_app(app) ---code
jyansinkai

2022/03/25 06:22

ご指導有難うございます。 server.pyの # ログインマネージャー準備 login_manager = LoginManager() login_manager.init_app(C_app) C_app.config['SECRET_KEY'] = 'secret' を、 # ログインマネージャー準備 login_manager = LoginManager() login_manager.init_app(app) app.config['SECRET_KEY'] = 'secret' と修正しました。 しかしながら、エラーメッセージは変わらず cannot import name 'C_app' from 'C.C' と出て参ります。 このエラーが出る場所が,server.pyの login_manager.init_app(app) より前の、モジュールをインポートする、 from C.C import C_app この部分で発生しているようです。
jyansinkai

2022/03/25 07:15

重ねてのご指導、誠に有難うございます。 ご指導の通り、C.pyから from server import login_manager を消しましたところ、 ImportError: cannot import name 'C_app' from 'C.C' (C:\C\C.py) は発生しなくなりました。 この from server import login_manager は、C.pyの処理に @login_manager.user_loader def load_user(user_id): return users.get(int(user_id)) というものがあり、 from server import login_manager を消すと、 NameError: name 'login_manager' is not defined とエラーが出てしまう状況だった為、 from server import login_manager を書いておいたという次第でした。 ということは、 @login_manager.user_loader で定義する処理は、server.pyに書くべきものとなるのでしょうか?
FiroProchainezo

2022/03/25 07:31

そうですね C.pyでインポートできないなら、server.pyで定義するしかないでしょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問