我对 Flask 还比较陌生,正在尝试使用装饰器的强大功能 :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
也许我没有正确理解装饰器的用法... 我可以这样使用我的装饰器吗?还是需要重新编写其他内容?
group_id
作为显式参数传递。在调用时,Python 会从**...
映射中解包参数。如果测试失败,则是因为包装器没有将group_id
传递给视图函数。 - Martijn Pietersfunc
,但是这里的装饰器明确期望被装饰的函数至少接受一个位置参数group_id
。你提供的其他帖子可能会删除该要求,但这并不是使此装饰器正常工作的严格要求。如果它对你不起作用,那么肯定有其他问题。 - Martijn Pietersrequest
对象是特殊的,只要有活动请求,它就可以在任何函数中使用。只需将group_id
参数设置为带有默认值的关键字参数,例如group_id=None
,并在装饰器中测试该默认值(if group_id is None:
),然后查看请求以获取该值。 - Martijn Pieters