从Flask导航访问Flask会话变量以获取动态导航菜单 [英] Accessing Flask Session variables from Flask Navigation for dynamic navigation menu
问题描述
我想要一个动态的导航菜单,如果用户当前没有登录,显示Login,如果用户登录,则显示Logout。
我使用类似如下的代码:
import flask
import flask_nav
import flask_nav。元素作为fne
frontend = flask.Blueprint('frontend',__name__)
application = flask.Flask(__ name__)
mySess = flask_session.Session()
flask_appconfig.AppConfig(应用程序)
flask_bootstrap.Bootstrap(应用程序)
application.register_blueprint(前端)
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()
$ b $ 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(应用程序)
@ nav.navigation()
def top_nav():
items = [fne.View('Home','.index')]
如果'google_token'在flask.session中:
items.append(fne.View('Logout', '.logout'))
在flask.session中的elif'auth_url':
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(帮助和放大器; ('',* items)
nav.register_element('frontend_top',top_nav())$ b返回fne.Navbar('',* items)
$ b
不幸的是,Flask会话变量超出了nav对象的范围,所以我无法访问flask。当然我也有同样的困难,当我在应用程序之外访问flask-session的任何独立函数时,例如
def user_is_logged_in():
如果flask.session中的'google_token':
返回True
else:
返回False
返回False
这些函数给出了预期的错误RuntimeError:Working在请求上下文之外。
为了安全起见,我不想在我的application.py代码中使用全局变量,所以多人可以访问应用程序同时没有错误。我相信SESSION应该存储用户是否正在登录。
如何让我的flask_nav.Nav()看到我的应用程序的flask.session?
您可以在应用程序中存在请求上下文的时候覆盖template_global的注册。
nav = Nav()
#注册顶级菜单栏
navitems = [
查看('Widgits,Inc.','index'),
查看('我们的任务','约'),
]
设置一个函数返回基于会话
def with_user_session_action(items):
return(
items
+查看('登录','登录')如果不是session.get('logged')其他视图('注销','注销')]
)
在一个委托给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
$ b $ def render_template(* args,** kwargs):
register_element(nav,navitems)
return _render_template(* args,nav = nav.elems,** kwargs)
奖金:
您可以缓存用于登录/注销的计算导航,以便不仅为每个个案计算一次。
I want to have a dynamic navigation menu that shows "Login" if the user is not currently logged on, and "Logout" if the user is logged in.
I'm using code similar to the following:
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())
Unfortunately, the Flask session variables are out-of-scope for the nav object, so I cannot access flask.session from within top_nav.
I have the same difficulty when I make any stand-alone function for accessing flask-session outside of my application, for example
def user_is_logged_in():
if 'google_token' in flask.session:
return True
else:
return False
return False
These functions give the expected error "RuntimeError: Working outside of request context."
I do NOT want to use a global variable in my application.py code for the user for security reasons and so multiple people can access the application at the same time without errors. I believe the SESSION should be storing whether the user is currently logged in or not.
How do I get my flask_nav.Nav() to see my application's flask.session?
flask_nav
registers extensions at a stage in the application lifecycle before requests start to be processed.
You can overwrite the registration of the template_global to later when a request context exists in the application.
Factor out common navigation items.
nav = Nav()
# registers the "top" menubar
navitems = [
View('Widgits, Inc.', 'index'),
View('Our Mission', 'about'),
]
Set a function to return an appropriate View/Link based on value in session
def with_user_session_action(items):
return (
items
+ [ View('Login', 'login') if not session.get('logged') else View('Logout', 'logout')]
)
Use this in a function that delegates to nav.register_element
def register_element(nav, navitems):
navitems = with_user_session_action(navitems)
return nav.register_element('top',
Navbar(*navitems)
)
Supersede render_template to always pass down the computed navigation
_render_template = render_template
def render_template(*args, **kwargs):
register_element(nav, navitems)
return _render_template(*args, nav=nav.elems, **kwargs)
Bonus:
You can cache the computed nav for login/logout so that it isn't only computed once for each case.
这篇关于从Flask导航访问Flask会话变量以获取动态导航菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!