How new_view works
Let's first look at the new_view function:
def new_view(request, *args, **kwargs):
if not request.user.is_authenticated():
return HttpResponseRedirect('/accounts/login/')
return view(request, *args, **kwargs)
When new_view is called, it checks whether the user is authenticated. If the user is authenticated, then new_view calls view and passes it all of the arguments (request, positional arguments, and keyword arguments).
Defining new_view
new_view is not automatically executed. We are using def to define the function, but we are not executing it right away. Instead, we return new_view as a function. Imagine the following code:
def my_view(request):
# ... some view stuff happens here
my_new_view = requires_login(my_view)
Now, my_new_view is a function. I can call it just like any other function. At no point so far has this new function actually been called.
When my_new_view is called, it receives all its arguments. It then calls my_view, passing all the arguments (request, positional arguments, and keyword arguments) to my_view instead.
(All of this assumes that the user is authenticated, of course. Otherwise, when you call my_new_view, you would get an HttpResponseRedirect, and my_view would never be called.)
view as an argument
requires_login receives a function called view as its argument. view refers to a function, but we're not executing that function yet. view is executed only when new_view is executed.