如何使用 Flask 使 class 变量可用于 Jinja2 模板?
How can I make a class variable available to Jinja2 templates with Flask?
我有一个使用 flask-login 的模板,并且我有一个基于位集的权限模型。在我的模板中,我想根据权限公开页面中的内容。我的用户模型中有一个函数 can(permission)
可以控制用户可以做什么。
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(64), unique=True)
fullname = db.Column(db.String(75))
password_hash = db.Column(db.String(128))
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
@property
def password(self):
raise AttributeError('password is not a readable attribute')
@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)
def verify_password(self, password):
return check_password_hash(self.password_hash, password)
def can(self, permissions):
return self.role is not None and (self.role.permissions & permissions) == permissions
def __repr__(self):
return '<User: {}>'.format(self.email)
class Permission:
FOLLOW = 0x01
COMMENT = 0x02
WRITE_ARTICLES = 0x04
MODERATE_COMMENTS = 0x08
ADMINISTER = 0x80
当我尝试在我的模板中调用 can()
函数并向其传递权限时,我得到一个错误,指出权限未定义,大概是因为权限 class 不在范围内模板。这是我的 base.html 所有其他模板扩展的一部分:
{% if current_user.can(Permission.ADMINISTER) %}
<h3>Administration</h3>
<ul>
<li><a href="{{ url_for('main.add_user') }}">Add User</a></li>
<li><a href="{{ url_for('main.change_password') }}">Change Password</a></li>
<li><a href="{{ url_for('main.lock_user') }}">Lock User</a></li>
</ul>
{% endif %}
我正在大致关注 Miguel Grinberg 关于 Flask Web 开发的书,他在他的 base.html (line 32).
中做同样的事情
如何使权限 class 可用于我的模板?
最明显但最不方便的是,在渲染需要它的模板时传递 Permission
class。
return render_template('page.html', Permission=Permission)
更进一步,告诉 Flask 自动将其添加到模板上下文中。在设置您的应用程序时在某处装饰上下文处理器。
@app.context_processor
def include_permission_class():
return {'Permission': Permission}
出于性能和清晰度的原因,上下文仅对正在呈现的即时模板可用。如果您需要它在 {% import %}
或 {% include %}
中可用,您可以将 with context
添加到需要它的每个块:{% include 'other_template.html' with context%}
。或者,您可以将 class 添加到 Jinja env 的全局命名空间。
app.add_template_global(Permission, 'Permission')
我有一个使用 flask-login 的模板,并且我有一个基于位集的权限模型。在我的模板中,我想根据权限公开页面中的内容。我的用户模型中有一个函数 can(permission)
可以控制用户可以做什么。
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(64), unique=True)
fullname = db.Column(db.String(75))
password_hash = db.Column(db.String(128))
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
@property
def password(self):
raise AttributeError('password is not a readable attribute')
@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)
def verify_password(self, password):
return check_password_hash(self.password_hash, password)
def can(self, permissions):
return self.role is not None and (self.role.permissions & permissions) == permissions
def __repr__(self):
return '<User: {}>'.format(self.email)
class Permission:
FOLLOW = 0x01
COMMENT = 0x02
WRITE_ARTICLES = 0x04
MODERATE_COMMENTS = 0x08
ADMINISTER = 0x80
当我尝试在我的模板中调用 can()
函数并向其传递权限时,我得到一个错误,指出权限未定义,大概是因为权限 class 不在范围内模板。这是我的 base.html 所有其他模板扩展的一部分:
{% if current_user.can(Permission.ADMINISTER) %}
<h3>Administration</h3>
<ul>
<li><a href="{{ url_for('main.add_user') }}">Add User</a></li>
<li><a href="{{ url_for('main.change_password') }}">Change Password</a></li>
<li><a href="{{ url_for('main.lock_user') }}">Lock User</a></li>
</ul>
{% endif %}
我正在大致关注 Miguel Grinberg 关于 Flask Web 开发的书,他在他的 base.html (line 32).
中做同样的事情如何使权限 class 可用于我的模板?
最明显但最不方便的是,在渲染需要它的模板时传递 Permission
class。
return render_template('page.html', Permission=Permission)
更进一步,告诉 Flask 自动将其添加到模板上下文中。在设置您的应用程序时在某处装饰上下文处理器。
@app.context_processor
def include_permission_class():
return {'Permission': Permission}
出于性能和清晰度的原因,上下文仅对正在呈现的即时模板可用。如果您需要它在 {% import %}
或 {% include %}
中可用,您可以将 with context
添加到需要它的每个块:{% include 'other_template.html' with context%}
。或者,您可以将 class 添加到 Jinja env 的全局命名空间。
app.add_template_global(Permission, 'Permission')