Flask decorator:无法从URL传递参数

时间:2013-08-19 09:27:22

标签: python flask decorator python-decorators

我是一个很新的烧瓶,我正在尝试使用装饰器的浮动力:p 我阅读了很多东西,发现了很多关于python装饰器的主题,但没有什么真正有用的。

@app.route('groups/<id_group>')
@group_required(id_group)
@login_required
def groups_groupIndex(id_group):
    #do some stuff
    return render_template('index_group.html')

这是我得到的错误:

@group_required(id_group), NameError: name 'id_group' is not defined

好的,id_group尚未定义,但我不明白为什么我可以在函数groups_groupIndex中使用URL中的id_group参数,但不能在装饰器中使用!

我尝试移动/切换装饰器,但每次都会出现同样的错误。

这是我的装饰者,但似乎工作正常

def group_required(group_id):
    def decorated(func):
        @wraps(func)
        def inner (*args, **kwargs):
            #Core_usergroup : table to match users and groups
            groups = Core_usergroup.query.filter_by(user_id = g.user.id).all()
            for group in groups:
                #if the current user is in the group : return func
                if int(group.group_id) == int(group_id) :
                    return func(*args, **kwargs)
            flash(gettext('You have no right on this group'))
            return render_template('access_denied.html')     
        return inner
    return decorated

也许我没有看到像我这样的装饰者......我可以这样使用我的装饰者还是需要重写不同的东西?

1 个答案:

答案 0 :(得分:10)

您将group_id定义为函数参数;这使它成为该函数的本地名称。

这不会使该名称可用于其他范围;装饰器所在的全局命名空间无法看到该名称。

包装器函数可以。调用时,它将从@apps.route()包装器传递该参数:

def group_required():
    @wraps(func)
    def wrapper(group_id, *args, **kwargs):
        #Core_usergroup : table to match users and groups
        groups = Core_usergroup.query.filter_by(user_id = g.user.id).all()
        for group in groups:
            #if the current user is in the group : return func
            if int(group.group_id) == int(group_id) :
                return func(*args, **kwargs)
        flash(gettext('You have no right on this group'))
        return render_template('access_denied.html')     
    return wrapper

请注意,此装饰器不会将group_id参数传递给装饰函数;使用return func(group_id, *args, **kwargs)而不是您仍需要在视图函数中访问该值。