gpt4 book ai didi

python - Django 编码 - 为什么需要返回两个相同的参数?

转载 作者:太空宇宙 更新时间:2023-11-03 20:16:13 24 4
gpt4 key购买 nike

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

为什么函数“password_reset_confirm”需要在单独的括号中返回两个 **kwargs 并它们在“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",)

View .py

from django.contrib.auth import views as django_views

class PasswordResetConfirm(django_views.PasswordResetConfirmView):
template_name = "account/password_reset_from_key.html"
success_url = reverse_lazy("account:reset-password-complete")
token = None
uidb64 = None

def form_valid(self, form):
response = super(PasswordResetConfirm, self).form_valid(form)
account_events.customer_password_reset_event(user=self.user)
return response

def password_reset_confirm(request, uidb64=None, token=None):
kwargs = {
"template_name": "account/password_reset_from_key.html",
"success_url": reverse_lazy("account:reset-password-complete"),
"token": token,
"uidb64": uidb64,
}
return PasswordResetConfirm.as_view(**kwargs)(request, **kwargs)

最佳答案

第一个变量 (uidb64) 只是从数据库中提取的用户的 Base64 编码 ID。通过该字段,Django 可以确定哪个用户正在请求密码重置。

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

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

  1. Django 不在数据库中存储密码重置 token 。许多其他框架都会这样做,并且在用户单击密码重置 URL 后,将在数据库中找到 token ,并从该数据库条目中确定请求重置的用户。相反,Django 使用一些巧妙的加密方法,并根据数据库中存储的 SECRET_KEY、当前用户密码哈希和生成此 token 的时间生成此 token 。之后,只能从 token 中提取时间,并通过从设置中获取用户数据和SECRET_KEY,Django可以验证密码重置 token 对于指定用户是否有效。 token 生成时间在这里,因此每个 token 在一段时间后都会过期。
  2. 用户 ID 不能轻易嵌入到 token 中,因为用户 ID 格式可以自定义(您可以嵌入自己的用户模型,例如使用 UUID 而不是数值)。这就是 Django 使用 Base64 对该 ID 进行编码的原因 - 它保证每种格式的用户 ID 都可以轻松嵌入到 URL 中。因此,用户 ID 可以具有不同的长度和格式,因此从 token 字符串中提取它并不容易。

至于两次传递 kwargs,这里是通过示例进行的快速解释:

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

def some_factory():
def some_function():
print('abc')
return some_function

my_function = some_factory()

在这个例子中,print不会被调用,因为我们没有执行some_functionsome_factory返回它,所以我们可以稍后使用它:

my_function()

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

some_factory()()

这就是第二个括号的来源。当然,这两个函数都可以接受一些参数,然后您将为第一对括号内的工厂提供参数,并为第二对括号内的 some_function 提供参数。

回到你的例子,它实际上是无效的,你不应该将完整的kwargs传递给PasswordResetConfirm中的as_view。它应该只需要前两个(template_namesuccess_url)。实际 View (第二个括号)应采用另外两个(tokenuidb64)。

代码中的第二个问题是您在每个请求上调用 as_view 。它被设计为在创建此 View 时仅调用一次。不要将其包装在单独的函数中,而是直接在 urls.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",
)

关于python - Django 编码 - 为什么需要返回两个相同的参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58428611/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com