在 Django 中,方法中的请求参数有什么作用?

In Django what does the request argument in a method do?

我看到一些代码,有时 身份验证方法 请求参数 而其他时候没有,例如请参阅以下代码:

代码 1:

def register(request):
     
    if request.method == 'POST':
        form = UserCreationForm(request.POST)

        if form.is_valid():
            form.save()
            # code for automatic login after singing up
            username = form.cleaned_data['username']
            password = form.cleaned_data['password1']
            user = authenticate<b>(username=username, password=password)</b>
            login<b>(request,</b> user)
            return redirect('/')
</pre>

代码2:

def login(request):
     
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate<b>(request, username=username, password=password)</b>
</pre>

根据官方docs

request is an HttpRequest and maybe None if it wasn’t provided to authenticate() (which passes it on to the backend).

这个 request 参数实际上做了什么,我什么时候应该考虑在 authenticate 方法中传递它?

你的问题的上下文是 django 是一个网络服务器。在经典的 HTTP/1 世界中,django 接收请求并 returns 响应。 request 参数通常表示从用户浏览器发送到 django 将响应的服务器的 http 请求。

因此,在您代码的第一个函数中,register 似乎旨在用作注册新用户的视图的一部分。在这种情况下,该请求对于允许注册功能访问用户在向网站注册该用户时输入的值很有用。登录也是如此。这些函数接受请求的唯一具体原因是它允许函数评估用户在请求中提交的信息并采取一些行动。

根据 Django 文档,并且我刚刚查看源代码确认,这将传递给您正在使用的任何身份验证后端的 authenticate 方法。

唯一似乎使用它的后端 class 是 RemoteUserBackend,这是因为 RemoteUserBackend 将在第一次用户(已经存在)时创建一个本地用户模型实例在远程 auth 数据库中)登录,然后,在返回用户实例之前,后端调用它自己的 configure_user 方法,传递新的用户实例,以及 request.

此处的文档:https://docs.djangoproject.com/en/3.1/ref/contrib/auth/#django.contrib.auth.backends.RemoteUserBackend

但是,这就是它变得愚蠢的地方.. configure_user 的默认实现实际上没有做任何事情,它只是一个存根,您可以在子class 中扩展它RemoteUserBackend 如果您想向其中添加自己的行为,您可以选择编写。

一尘不染。但确实是有道理的。也许在触发身份验证需要的请求中传递了一些参数,其中一些参数包含有关需要存储在新创建的用户实例中的用户的信息......请求对象包含有关请求的所有已知信息,它来自派上用场。

我只想说,某个时候有人编写了一个需要访问此时请求的身份验证后端,或者身份验证模块的作者预计有一天有人可能需要它。但是在 auth 模块本身,默认情况下,request 不用于我能看到的任何内容。

所以似乎没有必要将 request 传递给 authenticate,但是如果您能想象到将来您可能想要为您的应用程序配置一个时髦的身份验证后端,您可能想通过它..以防万一后端需要它。默认 ModelBackend 不使用它。