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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django授权 - 在函数调用中返回重定向相关的知识,希望对你有一定的参考价值。

我正在添加一些自定义授权来验证登录用户是否可以访问我的应用程序的特定部分。它不漂亮,但它的工作原理:

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):
  ...
答案

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

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授权 - 在函数调用中返回重定向的主要内容,如果未能解决你的问题,请参考以下文章

django重定向导致重定向到下一页,但然后返回原始?

Django之重定向

django 之redirect()函数全解

django 之redirect()函数全解

Django基础之redirect()

Django重定向:没有错误,但没有重定向[重复]