【发布时间】:2018-06-30 02:51:25
【问题描述】:
我正在添加一些自定义授权来验证登录用户是否有权访问我的应用程序的特定部分。它不漂亮,但它有效:
view_permissions = {
'admin_list': {
'school':{'userrole':['S','A'], 'usertype':[]},
'class':{'userrole':['S','A'], 'usertype':[]},
' ... '
},
'delete_object': { ... },
'edit_object': { ... },
}
}
def check_permissions(request, viewname, objecttype):
if(request.user.userrole in view_permissions[viewname][objecttype]['userrole'] or
request.user.usertype in view_permissions[viewname][objecttype]['usertype']
):
return True
else:
return False
def delete_object(request, objecttype, objectid):
# Redirect to home page if not authorized
if(not check_permissions(request, 'delete_object', objecttype)):
return redirect('wakemeup:index')
# Otherwise, continue processing
myobject.delete()
...
return admin_list(request, objecttype)
我想要做的是将redirect 移动到check_permissions 函数内,如下所示:
def check_permissions(request, viewname, objecttype):
if( <check permissions are valid> ):
pass # Authorized: Do nothing and continue with caller view logic
else:
return redirect('wakemeup:index') # Unauthorized: redirect to home
def delete_object(request, objecttype, objectid):
# Redirect to home page if not authorized
check_permissions(request, 'delete_object', objecttype))
问题在于,check_permissions 函数内的重定向没有任何作用。如果我将return 添加到调用逻辑,它只会重定向:
def delete_object(request, objecttype, objectid):
# Redirect to home page if not authorized
return check_permissions(request, 'delete_object', objecttype))
我猜这与嵌套函数调用将其输出一直返回给原始调用者有关。但是有没有一种简单的方法可以让重定向从 check_permissions 函数中工作?
编辑
更新的函数——我必须通过 args[0] 访问 request 对象,但我可以通过 kwargs 访问我的其他变量。我想这是因为在表单中,请求对象只是在幕后传递,而不是作为参数。
def check_perm(view):
viewname = view.__name__
def view_wrapper(*args, **kwargs):
objecttype = kwargs['objecttype']
myuser = args[0].user
if not (
myuser.userrole in view_permissions[viewname][objecttype]['userrole'] or
myuser.usertype in view_permissions[viewname][objecttype]['usertype']
):
# Invalid permission - redirect
return redirect('wakemeup:index')
# Valid permission - continue
return view(*args, **kwargs)
return view_wrapper
...
@check_perm
def delete_object(request, objecttype, objectid):
...
【问题讨论】:
-
这基本上意味着重写整个视图代码,但是如果您切换到使用基于类的视图和
PermissionRequiredMixin,这种事情会很多容易。 -
是的,很早就决定绕过 Django 的 ORM。这是一个非常令人头疼的问题,所以我已经吸取了下次的教训。感谢您的建议。
标签: python django redirect authorization