Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django授权-在函数调用中返回重定向_Python_Django_Redirect_Authorization - Fatal编程技术网

Python Django授权-在函数调用中返回重定向

Python Django授权-在函数调用中返回重定向,python,django,redirect,authorization,Python,Django,Redirect,Authorization,我正在添加一些自定义授权,以验证登录用户是否有权访问我的应用程序的特定部分。虽然不漂亮,但它很管用: view_permissions = { 'admin_list': { 'school':{'userrole':['S','A'], 'usertype':[]}, 'class':{'userrole':['S','A'], 'usertype':[]}, ' ... ' }, 'delete_object': { .

我正在添加一些自定义授权,以验证登录用户是否有权访问我的应用程序的特定部分。虽然不漂亮,但它很管用:

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)
我要做的是将
重定向
移动到
检查权限
函数中,类似这样:

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))
我猜这与嵌套函数调用将其输出返回给原始调用方有关。但是,有没有一种简单的方法可以让重定向在
检查权限
功能中工作

编辑 更新的函数——我必须通过args[0]访问
请求
对象,但我可以通过
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):
  ...

我认为函数装饰器是这个问题的完美解决方案。以下内容允许您检查条件(权限),必要时通过重定向劫持响应,如果没有,则继续正常视图响应:

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

另外,请注意它捕获视图名称的方式。在我看来更具动态性。

这基本上意味着重写整个视图代码,但如果您切换到使用基于类的视图和。是的,早些时候决定绕过Django的ORM,这类事情就会容易得多。这是一个非常令人头痛的问题,所以我已经为下一次的学习吸取了教训。谢谢你的建议。这太棒了!我想这就是我要找的。但是,如何在视图包装器中引用传递到视图中的变量(即请求、对象类型…)?我试着通过
kwargs
args
传递它们,但我无法引用它们。我成功了。请参见上面的编辑。非常感谢。这真是太棒了。@不客气!而且,根据您的编辑,我不确定您是否理解
*args
&
**kwargs
。如果您不理解它们,我建议您阅读本文,我认为使用**kwargs可以让我直接引用函数中的关键字参数(即
objecttype
),而不必使用
kwargs['objecttype']
)。不是这样吗?我是否应该以某种方式修改代码?@ravioli在函数定义的参数中列出了
**kwargs
,这样您就可以以字典的形式捕获以前未捕获的关键字参数。例如,如果函数的定义行是
def-view(foo=None,**kwargs)
我可以像
view(foo=1,hello=2,world=3)
一样调用它,并且
kwargs
在函数中的值为
{hello':2,'world':3}
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