【问题标题】:How can I make a class variable available to Jinja2 templates with Flask?如何使用 Flask 使类变量可用于 Jinja2 模板?
【发布时间】:2015-03-25 13:44:46
【问题描述】:

我有一个使用烧瓶登录的模板,并且我有一个基于位集的权限模型。在我的模板中,我想根据权限在页面中公开内容。我的用户模型中有一个函数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() 函数并向其传递权限时,我收到一个错误,即 Permission 未定义,可能是因为 Permission 类不在模板的范围内。这是我所有其他模板扩展的 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) 中也在做同样的事情。

如何使 Permission 类可用于我的模板?

【问题讨论】:

    标签: python flask jinja2


    【解决方案1】:

    最明显但最不方便的是,在渲染需要它的模板时传递Permission 类。

    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%}。或者,您可以将该类添加到 Jinja env 的全局命名空间中。

    app.add_template_global(Permission, 'Permission')
    

    【讨论】:

      猜你喜欢
      • 2015-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-29
      • 2020-09-21
      • 2016-05-23
      • 2015-12-08
      • 2021-04-22
      相关资源
      最近更新 更多