如何基于自定义装饰器管理员角色显示/隐藏导航栏项目



decorators.py


from functools import wraps
from flask import flash, redirect, url_for
from flask_login import current_user

def admin_required(f):
@wraps(f)
def wrap(*args, **kwargs):
if current_user.role == "Admin":
return f(*args, **kwargs)
else:
flash("You need to be an admin to view this page.")
return redirect(url_for('account'))
return wrap

我可以使用current_user.is_authenticated在jinja中隐藏/显示导航栏项目,但我似乎无法使用用户角色来处理它。有人知道我如何根据用户的角色更改基本模板中的导航栏项目吗?

base.html

<div class="navbar-nav">
{% if current_user.is_authenticated %}
{{ render_nav_item('account', 'Account', use_li=True) }}
{{ render_nav_item('logout', 'Logout', use_li=True) }}
{% elif current_user.role == "Admin" %}
{{ render_nav_item('admin_panel', 'Admin Panel', use_li=True) }}
{% else %}
{{ render_nav_item('login', 'Login', use_li=True) }}
{% endif %}
</div>

型号.py

class User(db.Model, UserMixin):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
weekly_time = db.relationship('WeeklyTime', backref=db.backref('user'), lazy=True)
weekly_expense = db.relationship('WeeklyExpense', backref=db.backref('user'), lazy=True)
name = db.Column(db.String(120), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.String(120), nullable=False)
account_creation_datetime = db.Column(db.DateTime, nullable=False)
role = db.Column(db.String(45), nullable=False)
confirmed = db.Column(db.Boolean, nullable=False, default=False)
confirmed_on = db.Column(db.DateTime, nullable=True)
password_reset_token = db.Column(db.String(120), nullable=True)

def __repr__(self):
return f"User('{self.name}', '{self.email}')"

管理员角色是否经过身份验证?也就是说,对于管理员角色,if current_user.is_authenticated是否评估为True?在这种情况下,if语句在第一个条件下终止。您需要一个单独的if条件来测试经过身份验证的用户是否是管理员。

{% if current_user.is_authenticated %}
{{ render_nav_item('account', 'Account', use_li=True) }}
{{ render_nav_item('logout', 'Logout', use_li=True) }}
{% if current_user.role == "Admin" %}
{{ render_nav_item('admin_panel', 'Admin Panel', use_li=True) }}
{% endif %}
{% else %}
{{ render_nav_item('login', 'Login', use_li=True) }}
{% endif %}

只需在应用程序app.py中声明两个topbar,top和top2:

...
from flask_login import UserMixin, LoginManager, login_required, current_user, login_user, logout_user
...
nav = Nav()
# registers the "top" menubar
nav.register_element('top', Navbar(logo,
View('Home', 'index'),                                   
View('LogIn', 'login'),  # login
View('SignUp', 'signup'),  # signup
))
# registers the "top2" menubar
nav.register_element('top2', Navbar(logo,
View('Home', 'index'),
View('Profile', 'profile'),  # def profile                                    
View('LogOut', 'logout'),  # def logout
))

现在在你的base.html中,你可以选择if块作为:

<body>
{% block navbar %}
{% if current_user.is_authenticated %}
{{nav.top2.render()}}
{% else %} 
{{nav.top.render()}}
{% endif %}    
{% endblock %}
...
</body>

最新更新