Python Django编码-为什么必须返回两个相同的参数?

Python Django编码-为什么必须返回两个相同的参数?,python,django,Python,Django,我正在寻找在Django中添加电子邮件帐户验证,并找到了一个很好的开源代码,我可以采用。 但有一行我不熟悉 为什么“密码重置确认”功能需要返回两个**KWARG,分别放在括号和 在类“PasswordResetConfirm”中如何使用它们 这个问题可能与Python有关,而不是与Django有关。但无论如何,谢谢你的帮助 url.py url(r"^password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za

我正在寻找在Django中添加电子邮件帐户验证,并找到了一个很好的开源代码,我可以采用。 但有一行我不熟悉

为什么“密码重置确认”功能需要返回两个**KWARG,分别放在括号和 在类“PasswordResetConfirm”中如何使用它们

这个问题可能与Python有关,而不是与Django有关。但无论如何,谢谢你的帮助

url.py

url(r"^password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za- 
z]{1,13}-[0-9A-Za-z]{1,20})/$",views.password_reset_confirm, name="reset- 
password-confirm",)
第一个变量(
uidb64
)就是从数据库中提取的用户的base64编码ID。通过此字段,Django可以确定哪个用户正在请求密码重置

第二个变量(
令牌
)是用于验证用户请求的实际重置令牌。用户只能从发送给他的电子邮件中获取此令牌,因此这将验证用户是否有权访问提供的电子邮件地址,以便我们可以继续重置密码

为什么我们不能单独使用
令牌
?这有两个原因

  • Django不在数据库中存储密码重置令牌。许多其他框架都会这样做,在用户单击密码重置URL后,将在数据库中找到令牌,并从该数据库条目中确定请求重置的用户。相反,Django使用了一些巧妙的加密方法,并根据存储在数据库中的
    SECRET\u KEY
    、当前用户密码散列和生成此令牌的时间生成此令牌。之后,只能从令牌中提取时间,通过从设置中获取用户数据和
    密钥
    ,Django可以验证密码重置令牌对指定用户有效。令牌生成的时间就在这里,所以每个令牌都可能在一段时间后过期
  • 用户ID不能像时间一样轻松地嵌入到令牌中,因为用户ID格式可以自定义(您可以嵌入自己的用户模型,例如使用UUID而不是数值)。这就是Django使用Base64编码这个ID的原因——它保证每个格式的用户ID都可以轻松地嵌入到URL中。由于这个原因,用户ID可以有不同的长度和格式,所以从令牌字符串中提取它并不容易
  • 关于两次通过kwargs,下面通过示例快速说明:

    在python中,您可以通过调用任何其他函数或方法返回函数(这些函数通常称为工厂):

    在本例中,不会调用print,因为我们没有执行
    some\u函数
    some\u工厂
    返回它,所以我们可以稍后使用它:

    my_function()
    
    现在将调用此打印,我们将在控制台输出中看到
    abc
    。但是,您可以立即调用它,而不是将返回的函数分配给某个变量或将其传递到某个地方:

    some_factory()()
    
    这就是第二个括号的来源。当然,这两个函数都可以接受一些参数,然后在第一对括号中为factory提供参数,在第二对括号中为
    某个函数提供参数

    回到您的示例,它实际上是无效的,您不应该在
    PasswordResetConfirm
    中将完整的kwargs传递给
    as\u view
    。它应该只使用前两个(
    template\u name
    success\u url
    )。实际视图(第二个括号)应采用另外两个(
    token
    uidb64

    代码中的第二个错误是,您在每次请求时都以查看方式调用
    。它被设计为在创建此视图时只调用一次。不要将其包装在单独的函数中,而是直接在
    url.py中使用它:

    url(
        r"^password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$",
        PasswordResetConfirm.as_view(
            template_name="account/password_reset_from_key.html"
            success_url=reverse_lazy("account:reset-password-complete"),
        ), name="reset-password-confirm",
    )
    
    url(
    r“^password/reset/(?P[0-9A-Za-z_ \-])/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$”,
    PasswordResetConfirm.as\u视图(
    template\u name=“account/password\u reset\u from\u key.html”
    成功\u url=reverse\u lazy(“帐户:重置密码完成”),
    ),name=“重置密码确认”,
    )
    
    第一个变量(
    uidb64
    )就是从数据库中提取的用户的base64编码ID。通过此字段,Django可以确定哪个用户正在请求密码重置

    第二个变量(
    令牌
    )是用于验证用户请求的实际重置令牌。用户只能从发送给他的电子邮件中获取此令牌,因此这将验证用户是否有权访问提供的电子邮件地址,以便我们可以继续重置密码

    为什么我们不能单独使用
    令牌
    ?这有两个原因

  • Django不在数据库中存储密码重置令牌。许多其他框架都会这样做,在用户单击密码重置URL后,将在数据库中找到令牌,并从该数据库条目中确定请求重置的用户。相反,Django使用了一些巧妙的加密方法,并根据存储在数据库中的
    SECRET\u KEY
    、当前用户密码散列和生成此令牌的时间生成此令牌。之后,只能从令牌中提取时间,通过从设置中获取用户数据和
    密钥
    ,Django可以验证密码重置令牌对指定用户有效。令牌生成的时间就在这里,所以每个令牌都可能在一段时间后过期
  • 用户ID不能像时间一样轻松地嵌入到令牌中,因为用户ID格式可以自定义(您可以嵌入自己的用户模型,例如使用UUID而不是数值)。这就是Django使用Base64编码这个ID的原因——它保证每个格式的用户ID都可以轻松地嵌入到URL中。由于这个原因,用户ID可以有不同的长度和格式,所以从令牌字符串中提取它并不容易
  • 关于两次通过kwargs,下面通过示例快速说明:

    在python中,您可以通过调用任何其他函数或方法返回函数(这些函数通常称为工厂):

    在本例中,不会调用print,因为我们没有执行
    some\u函数
    some\u工厂
    返回它,所以我们可以稍后使用它:

    my_function()
    

    url( r"^password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$", PasswordResetConfirm.as_view( template_name="account/password_reset_from_key.html" success_url=reverse_lazy("account:reset-password-complete"), ), name="reset-password-confirm", )