我正在添加一些自定义授权,以验证登录用户是否可以访问我的应用程序的特定部分。它不漂亮,但是可以工作:
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):
...
答案 0 :(得分:2)
我认为函数装饰器是解决此问题的完美解决方案。以下内容使您可以检查条件(权限),并在必要时通过重定向劫持响应,如果没有,则继续执行常规的视图响应:
from django.shortcuts import redirect
def check_permissions(view):
view_name = view.__name__
def view_wrapper(*args, **kwargs):
# Check permissions here.
if False or False or True:
# Hijack response with a redirect if conditions not met.
return redirect('wakemeup:index')
# Conditions met, continue with normal response.
return view(*args, **kwargs)
return view_wrapper
@check_permissions
def delete_object(request, object_type, object_id):
# Your normal view...
return
此外,请注意其捕获视图名称的方式。我认为动态性更大。