Basic Django - 视图包装器如何接收请求,关键字和位置参数?

gro*_*ark 6 django django-templates django-models django-admin django-views

Django书的第8章中,有一个示例显示了一个基本的视图包装方法,该方法接收从任意单个任意URLconf传入的另一个视图方法:

def requires_login(view):
    def new_view(request, *args, **kwargs):
        if not request.user.is_authenticated():
            return HttpResponseRedirect('/accounts/login/')
        return view(request, *args, **kwargs)
    return new_view
Run Code Online (Sandbox Code Playgroud)

我遵循这里的大部分逻辑,但我不理解的是嵌套new_view定义如何接收请求,*args和**kwargs因为它没有被明确地传递给requires_login定义.

new_view接受这些论点的定义究竟如何?

Wes*_*ley 4

如何new_view运作

我们先看一下函数new_view

def new_view(request, *args, **kwargs):
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/accounts/login/')
    return view(request, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

调用时new_view,它会检查用户是否经过身份验证。如果用户已通过身份验证,则new_view调用view并向其传递所有参数(request、位置参数和关键字参数)。

定义new_view

new_view不会自动执行。我们正在用来def定义函数,但我们不会立即执行它。相反,我们new_view作为函数返回。想象一下下面的代码:

def my_view(request):
    # ... some view stuff happens here

my_new_view = requires_login(my_view)
Run Code Online (Sandbox Code Playgroud)

现在,my_new_view是一个函数。我可以像调用任何其他函数一样调用它。到目前为止,这个新函数还没有被真正调用过。

my_new_view被调用时,它接收所有参数。然后它调用my_view,将所有参数(request、位置参数和关键字参数)传递给my_view

(当然,所有这些都假设用户已通过身份验证。否则,当您调用 时my_new_view,您将得到一个HttpResponseRedirect, 并且my_view永远不会被调用。)

view作为一个论点

requires_login接收一个名为的函数view作为其参数。view引用一个函数,但我们还没有执行该函数。view仅当new_view执行时才执行。