Базовый Django - Как обертки представления получают запрос, ключевое слово и позиционные аргументы? - PullRequest
6 голосов
/ 19 февраля 2010

В главе 8 книги Django приведен пример, демонстрирующий метод фундаментального переноса вида, который получает другой метод представления, переданный из любого произвольного 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

Я следую большей части логики здесь, но я не понимаю, как вложенное определение new_view получает запрос, * args и ** kwargs, поскольку оно явно не передается в определение requires_login.

Как именно определение new_view получает эти аргументы?

1 Ответ

4 голосов
/ 19 февраля 2010

Как 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)

Когда вызывается 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)

Теперь 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.

...