Django装饰器获取WSGIRequest而非预期的函数参数

1 投票
2 回答
897 浏览
提问于 2025-04-15 19:27

我正在为Django的视图创建一个装饰器,这个装饰器会检查一个不由Django管理的数据库中的权限。下面是这个装饰器的代码:

def check_ownership(failure_redirect_url='/', *args, **kwargs):
    def _check_ownership(view):
        def _wrapper(request, csi=None):
            try:
                opb_id=request.user.get_profile().opb_id
                if opb_id and csi and model.is_users_server(opb_id, csi):
                    return view(*args, **kwargs)
            except Exception, e:
                logger.debug("Exception checking ownership: %s", str(e))
            return HttpResponseRedirect(failure_redirect_url)
        _wrapper.__dict__=view.__dict__
        _wrapper.__doc__=view.__doc__
        return _wrapper
    return _check_ownership

这是它的使用方式:

@check_ownership
def my_view(request, csi=None):
    """Process my request"""

check_ownership()这个函数被调用,并返回了_check_ownership()。当调用_check_ownership()时,它是用一个WSGIRequest对象来调用的,我本来期待的是_wrapper()会用这个对象来调用。有没有人知道我的方法去哪儿了,怎么才能找回来?目前的情况是我没有办法连接到下一个装饰器或者实际的视图。

哦,我用的是CentOS上的Python 2.4.3和Django 1.1.1。

我想要我的函数回来!;)

谢谢。

tj

2 个回答

0

这个问题跟装饰器是怎么被调用的有关。你会发现这两种写法的表现是不一样的:

@my_decorator

@my_decorator(someparam='someval')

在第一种情况下,你直接把可调用的对象传给了my_decorator。而在第二种情况下,你没有直接传,但从my_decorator返回的可调用对象会被传递。

我相信这其中有一些深奥的原因,但在我看来,这实在是太糟糕了。这让创建带有默认参数的装饰器变得不那么清晰,应该更简单才对。

1
@check_ownership
def my_view(request, csi=None):
    ...

翻译成:

def my_view(request, csi=None):
    ...
my_view = check_ownership(my_view)

但是 check_ownership 不接受一个函数,而 _check_ownership 是可以的。这可能就是你问题的所在。

撰写回答