3

ユーザーが現在ログオンしていない場合は「ログイン」、ユーザーがログインしている場合は「ログアウト」を表示するダイナミック ナビゲーション メニューが必要です。

次のようなコードを使用しています。

import flask
import flask_nav
import flask_nav.elements as fne

frontend = flask.Blueprint('frontend', __name__)

application = flask.Flask(__name__)
mySess = flask_session.Session()

flask_appconfig.AppConfig(application)
flask_bootstrap.Bootstrap(application)
application.register_blueprint(frontend)
application.config['BOOTSTRAP_SERVE_LOCAL'] = True
application.config['SSL'] = True
application.secret_key = SECRET_KEY
application.config['SESSION_TYPE'] = SESSION_TYPE

mySess.init_app(application)

nav = flask_nav.Nav()

class CustomRenderer(flask_bootstrap.nav.BootstrapRenderer):
    def visit_Navbar(self, node):
        nav_tag = super(CustomRenderer, self).visit_Navbar(node)
        nav_tag['class'] = 'navbar navbar-default navbar-fixed-top'
        return nav_tag

flask_nav.register_renderer(application, 'custom', CustomRenderer)

nav.init_app(application)

@nav.navigation()
def top_nav():
    items = [ fne.View('Home',              '.index') ]

    if 'google_token' in flask.session:
        items.append(fne.View('Logout',         '.logout'))
    elif 'auth_url' in flask.session:
        items.append(fne.View('Login',          flask.session['auth_url']))
    else:
        items.append(fne.View('Login',          '.login'))

    items.append(fne.View('About',              '.about'))
    items.append(fne.View('Contact',            '.contact'))
    items.append(fne.View('Shop',               '.shop'))
    items.append(fne.View('Help & Feedback',    '.help'))

    return fne.Navbar('', *items)

nav.register_element('frontend_top', top_nav())

残念ながら、Flask セッション変数は nav オブジェクトの範囲外であるため、top_nav 内からflask.session にアクセスできません。

たとえば、アプリケーションの外部でフラスコセッションにアクセスするためのスタンドアロン関数を作成するときも、同じ問題があります。

def user_is_logged_in():
    if 'google_token' in flask.session:
        return True
    else:
        return False
    return False

これらの関数は、予想されるエラー「RuntimeError: Working outside of request context.」を返します。

セキュリティ上の理由から、ユーザーの application.py コードでグローバル変数を使用したくないため、複数の人がエラーなしで同時にアプリケーションにアクセスできます。ユーザーが現在ログインしているかどうかに関係なく、SESSIONは保存する必要があると思います。

アプリケーションのflask.sessionを表示するためにflask_nav.Nav()を取得するにはどうすればよいですか?

4

2 に答える 2

3

flask_navリクエストの処理が開始される前のアプリケーション ライフサイクルの段階で拡張機能を登録します。

アプリケーションにリクエストコンテキストが存在する場合、template_global の登録を後で上書きできます。

一般的なナビゲーション項目を除外します。

nav = Nav()

# registers the "top" menubar
navitems = [
    View('Widgits, Inc.', 'index'),
    View('Our Mission', 'about'),
]

セッションの値に基づいて適切なビュー/リンクを返す関数を設定します

def with_user_session_action(items):
    return (
        items 
        + [ View('Login', 'login') if not session.get('logged') else View('Logout', 'logout')]
    )

nav.register_element に委譲する関数でこれを使用します。

def register_element(nav, navitems):
    navitems = with_user_session_action(navitems)
    return nav.register_element('top', 
        Navbar(*navitems)
    )

render_template を置き換えて、計算されたナビゲーションを常に渡す

_render_template = render_template

def render_template(*args, **kwargs):
    register_element(nav, navitems)

    return _render_template(*args, nav=nav.elems, **kwargs)

ボーナス:

ログイン/ログアウトの計算されたナビゲーションをキャッシュして、ケースごとに一度だけ計算されないようにすることができます。

于 2017-10-10T11:37:19.923 に答える