python-3.x 在Django中定义视图和url,为什么调用函数时不用括号?

nue99wik  于 2023-04-13  发布在  Python
关注(0)|答案(2)|浏览(111)

我一直在经历“Python速成班”,我正在进行“Django Web应用程序项目(学习日志)”阶段。有一些东西与我已经学到的东西相矛盾......

"""views.py file"""

from django.shortcuts import render

def index(request):
    """The home page for Learning Log."""
    return render(request, "learning_logs/index.html")
"""urls.py file"""

from django.urls import path

from . import views

app_name = "learning_logs"
urlpatterns = [
    # Home page
    path("", views.index, name="index")
]

在上面的代码中,在“urls.py“文件中,views.index被调用,但是没有括号,为什么呢?
另外,index函数有“(request)”参数,但从来没有提供实参。我错过了什么吗?

  • 请注意,此代码运行正常。*
t1qtbnec

t1qtbnec1#

因为如果你 call 函数,你将在加载文件时调用函数,这将产生一个TypeError,因为缺少一个参数(request)。
你在这里不 * 调用 * index视图,你 * 传递一个引用 * 到该视图。这意味着Django存储了一个对函数的引用,当发出请求时,它将调用该函数。
在Python中,就像许多其他语言一样,函数是“一等公民”。您可以将这些作为参数传递,将这些作为结果返回,等等。
例如,我们可以定义一个函数如下:

def two():
    return 2

def sum_twice(f):
    return f() + f()

如果我们调用sum_twice(two),那么我们将two函数的引用作为sum_twice中的f参数传递。这将调用f两次并对结果求和。在这里,它将因此返回4。如果我们使用sum_twice(two())调用它,那么f将是2,并且f()因此将不工作(并且引发错误)。

bfnvny8b

bfnvny8b2#

一个web应用程序或者任何web服务器基本上只做一件事。(尽管它可以,而且经常以非常复杂的方式来实现)。服务器监听来自客户端的 * 请求 *(通常是web浏览器,当用户点击链接时,或提交表单),然后将 * 响应 * 发送回客户端(在浏览器的情况下,这通常是HTML文档,然后将其显示给用户,但它也可以是许多其他东西,包括JSON或其他文件,如CSS,JS和图像文件,如果包含在HTML文档中,浏览器将请求这些文件,这些文件也是页面按预期运行所必需的)。
因此,任何web框架都需要做的是,无论它是用什么语言编写的,都是将 * 请求 * 转换为 * 响应 *。这就是你提到的任何语言的任何框架,实际上都是这样做的。并且将其建模为函数是非常自然的,它将请求(或者更确切地说是表示它的语言结构)作为输入,并将响应作为输出返回。
这正是Django所做的。当客户端向Django应用程序发出请求时,在高层次上基本上会发生的是,该请求被转换为Python对象,并作为其第一个参数传递给您的视图函数之一-该函数通常称为request,并且出于可读性的明显原因,该函数将返回HttpResponse对象,它代表了响应-通常你不需要自己构造,有一些方便的函数可以在提供其他信息时为你生成正确的响应,特别是renderredirect
URLconf是你告诉Django调用哪个函数的方式,也就是说,哪个函数应该处理请求,以便将响应返回给客户端。它是URL到视图函数的Map,每个path调用的第一个参数是模式(或者更一般地说,一组模式,从中可以提取变量,这些变量也传递给视图函数),而第二个是要调用的函数。(为此可以忽略第三个)正如Willem在他的回答中解释的那样,这与调用函数并不相同你只是简单地传递了一个所谓的“引用”到函数-一个Python对象-到path。你告诉Django“当一个请求被发送到这个URL,使用适当的请求对象“”调用此函数。但此时并没有调用它。

相关问题