装饰器可调用函数中传递

装饰器可调用函数中传递

本文介绍了如何在 user_passes_test 装饰器可调用函数中传递 Django 请求对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Django user_passes_test 装饰器来检查用户权限.

I am using Django user_passes_test decorator to check the User Permission.

@user_passes_test(lambda u: has_add_permission(u, "project"))
def create_project(request):
......

我正在调用一个回调函数 has_add_permission,它接受两个参数 User 和一个字符串.我想传递请求对象,这可能吗?另外,谁能告诉我我们如何能够直接访问装饰器内的用户对象.

I am calling a callback function has_add_permission which takes two arguments User and a String. I would like to pass the request object along with it is that possible? Also, can anyone please tell me how are we able to access the User object inside the decorator directly.

推荐答案

不,您不能将请求传递给 user_passes_test.要了解其工作原理和方式,只需转到 来源:

No, you cannot pass request to user_passes_test. To understand why and how it works, just head over to the source:

def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
    """
    Decorator for views that checks that the user passes the given test,
    redirecting to the log-in page if necessary. The test should be a callable
    that takes the user object and returns True if the user passes.
    """

    def decorator(view_func):
        @wraps(view_func, assigned=available_attrs(view_func))
        def _wrapped_view(request, *args, **kwargs):
            if test_func(request.user):
                return view_func(request, *args, **kwargs)
            path = request.build_absolute_uri()
            # If the login url is the same scheme and net location then just
            # use the path as the "next" url.
            login_scheme, login_netloc = urlparse.urlparse(login_url or
                                                        settings.LOGIN_URL)[:2]
            current_scheme, current_netloc = urlparse.urlparse(path)[:2]
            if ((not login_scheme or login_scheme == current_scheme) and
                (not login_netloc or login_netloc == current_netloc)):
                path = request.get_full_path()
            from django.contrib.auth.views import redirect_to_login
            return redirect_to_login(path, login_url, redirect_field_name)
        return _wrapped_view
    return decorator

这是 user_passes_test 装饰器背后的代码.正如你所看到的,传递给装饰器的测试函数(在你的例子中,lambda u: has_add_permission(u, "project"))只传递了一个参数,request.user.现在,当然可以编写自己的装饰器(甚至直接复制此代码并对其进行修改)来传递 request 本身,但是您不能使用默认的 user_passes_test 实现.

This is the code behind the user_passes_test decorator. As you can see, the test function passed to the decorator (in your case, lambda u: has_add_permission(u, "project")) is passed just one argument, request.user. Now, it's of course possible to write your own decorator (even copying this code directly and just modifying it) to also pass the request itself, but you can't do it with the default user_passes_test implementation.

这篇关于如何在 user_passes_test 装饰器可调用函数中传递 Django 请求对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-28 04:24