Django PasswordResetConfirmView 密码重置失败不起作用
Django PasswordResetConfirmView password reset failed not working
当使用 Django3.0 内部 PasswordResetConfirmView
PasswordResetForm
reset_password.html
并篡改生成的令牌时,会引发表单 "is_bound"
错误。它不会重定向到某些失败 url.
Internal Server Error: /account/password/reset/MQ/akbdyj-e5f18868fas35e748160dd6ef006803a5/
Traceback (most recent call last):
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\core\handlers\base.py", line 204, in _get_response
response = response.render()
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\response.py", line 108, in render
self.content = self.rendered_content
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\response.py", line 86, in rendered_content
return template.render(context, self._request)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\backends\django.py", line 61, in render
return self.template.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 170, in render
return self._render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 162, in _render
return self.nodelist.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 938, in render
bit = node.render_annotated(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 905, in render_annotated
return self.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\loader_tags.py", line 150, in render
return compiled_parent._render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 162, in _render
return self.nodelist.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 938, in render
bit = node.render_annotated(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 905, in render_annotated
return self.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\loader_tags.py", line 62, in render
result = block.nodelist.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 938, in render
bit = node.render_annotated(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 905, in render_annotated
return self.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\crispy_forms\templatetags\crispy_forms_tags.py", line 203, in render
c = self.get_render(context).flatten()
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\crispy_forms\templatetags\crispy_forms_tags.py", line 112, in get_render
node_context.update({"is_bound": actual_form.is_bound})
AttributeError: 'NoneType' object has no attribute 'is_bound'
我试过在“extra_context”中传递失败模板名称,但仍然无效。
class UserAccountResetPasswordView(PasswordResetConfirmView):
template_name = 'user_account/profile/reset_password.html'
form_class = UserAccountPasswordResetForm
success_url = reverse_lazy('user_account:login')
extra_context = {
'template_name': 'user_account/profile/reset_password_failed.html'
}
表格
class UserAccountPasswordResetForm(SetPasswordForm):
new_password1 = forms.CharField(
label=_("New password"),
strip=False,
widget=forms.PasswordInput(
attrs={
'class': 'form-control',
'id': 'toggle-password-type',
'placeholder': 'New Password'
}),
)
new_password2 = forms.CharField(
label=_("Confirm new password"),
strip=False,
widget=forms.PasswordInput(
attrs={
'class': 'form-control',
'placeholder': 'Confirm New Password'
}),
)
class Meta:
fields = ['new_password1', 'new_password2']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_show_labels = False
self.helper.form_tag = False
self.helper.layout = Layout(
Field(AppendedText('new_password1',
'<i onclick="passwordTypeToggle()" class="fa fa-eye"></i>')),
'new_password2',
)
def clean_new_password1(self):
new_password1 = self.cleaned_data.get("new_password1")
if not re.search(
"^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)[A-Za-z\d@!#$%&*()_+-= ]{8,}$",
new_password1
):
raise ValidationError(
'Password should have 8 to 15 characters which contain only characters, numeric digits, underscore and first character must be a letter', code='signup'
)
return new_password1
reset_password.html
{% extends 'base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content" id="container-fluid">
<div class="card shadow-sm rounded" style="max-width: 500px; margin: auto;">
<div class="card-body">
<h1>Reset Password</h1>
<hr>
<form method="post">
{% crispy form %}
<div class="row">
<div class="col-12 text-right">
<button type="submit" class="btn btn-primary">Confirm</button>
</div>
</div>
</form>
</div>
</div>
</div>
{% endblock content %}
在 extra_context
中传递模板名称没有任何作用。如果令牌无效,则 PasswordResetConfirmView
将 form
设置为 None
并将其传递给上下文。您尝试呈现该表单时出错。相反,您应该检查上下文中传递的变量 validlink
以指示 link 是否正确并正确呈现:
{% extends 'base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% block content %}
{% if validlink %}
<div class="content" id="container-fluid">
<div class="card shadow-sm rounded" style="max-width: 500px; margin: auto;">
<div class="card-body">
<h1>Reset Password</h1>
<hr>
<form method="post">
{% crispy form %}
<div class="row">
<div class="col-12 text-right">
<button type="submit" class="btn btn-primary">Confirm</button>
</div>
</div>
</form>
</div>
</div>
</div>
{% else %}
<!--Render here as per your preferences to indicate the link is invalid-->
Looks like you clicked on an invalid password reset link. Please try again.
{% endif %}
{% endblock content %}
当使用 Django3.0 内部 PasswordResetConfirmView
PasswordResetForm
reset_password.html
并篡改生成的令牌时,会引发表单 "is_bound"
错误。它不会重定向到某些失败 url.
Internal Server Error: /account/password/reset/MQ/akbdyj-e5f18868fas35e748160dd6ef006803a5/
Traceback (most recent call last):
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\core\handlers\base.py", line 204, in _get_response
response = response.render()
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\response.py", line 108, in render
self.content = self.rendered_content
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\response.py", line 86, in rendered_content
return template.render(context, self._request)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\backends\django.py", line 61, in render
return self.template.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 170, in render
return self._render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 162, in _render
return self.nodelist.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 938, in render
bit = node.render_annotated(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 905, in render_annotated
return self.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\loader_tags.py", line 150, in render
return compiled_parent._render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 162, in _render
return self.nodelist.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 938, in render
bit = node.render_annotated(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 905, in render_annotated
return self.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\loader_tags.py", line 62, in render
result = block.nodelist.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 938, in render
bit = node.render_annotated(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\django\template\base.py", line 905, in render_annotated
return self.render(context)
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\crispy_forms\templatetags\crispy_forms_tags.py", line 203, in render
c = self.get_render(context).flatten()
File "C:\Users\JoyStick\.virtualenvs\django-template-2StZ7f6a\lib\site-packages\crispy_forms\templatetags\crispy_forms_tags.py", line 112, in get_render
node_context.update({"is_bound": actual_form.is_bound})
AttributeError: 'NoneType' object has no attribute 'is_bound'
我试过在“extra_context”中传递失败模板名称,但仍然无效。
class UserAccountResetPasswordView(PasswordResetConfirmView):
template_name = 'user_account/profile/reset_password.html'
form_class = UserAccountPasswordResetForm
success_url = reverse_lazy('user_account:login')
extra_context = {
'template_name': 'user_account/profile/reset_password_failed.html'
}
表格
class UserAccountPasswordResetForm(SetPasswordForm):
new_password1 = forms.CharField(
label=_("New password"),
strip=False,
widget=forms.PasswordInput(
attrs={
'class': 'form-control',
'id': 'toggle-password-type',
'placeholder': 'New Password'
}),
)
new_password2 = forms.CharField(
label=_("Confirm new password"),
strip=False,
widget=forms.PasswordInput(
attrs={
'class': 'form-control',
'placeholder': 'Confirm New Password'
}),
)
class Meta:
fields = ['new_password1', 'new_password2']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_show_labels = False
self.helper.form_tag = False
self.helper.layout = Layout(
Field(AppendedText('new_password1',
'<i onclick="passwordTypeToggle()" class="fa fa-eye"></i>')),
'new_password2',
)
def clean_new_password1(self):
new_password1 = self.cleaned_data.get("new_password1")
if not re.search(
"^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)[A-Za-z\d@!#$%&*()_+-= ]{8,}$",
new_password1
):
raise ValidationError(
'Password should have 8 to 15 characters which contain only characters, numeric digits, underscore and first character must be a letter', code='signup'
)
return new_password1
reset_password.html
{% extends 'base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content" id="container-fluid">
<div class="card shadow-sm rounded" style="max-width: 500px; margin: auto;">
<div class="card-body">
<h1>Reset Password</h1>
<hr>
<form method="post">
{% crispy form %}
<div class="row">
<div class="col-12 text-right">
<button type="submit" class="btn btn-primary">Confirm</button>
</div>
</div>
</form>
</div>
</div>
</div>
{% endblock content %}
在 extra_context
中传递模板名称没有任何作用。如果令牌无效,则 PasswordResetConfirmView
将 form
设置为 None
并将其传递给上下文。您尝试呈现该表单时出错。相反,您应该检查上下文中传递的变量 validlink
以指示 link 是否正确并正确呈现:
{% extends 'base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% block content %}
{% if validlink %}
<div class="content" id="container-fluid">
<div class="card shadow-sm rounded" style="max-width: 500px; margin: auto;">
<div class="card-body">
<h1>Reset Password</h1>
<hr>
<form method="post">
{% crispy form %}
<div class="row">
<div class="col-12 text-right">
<button type="submit" class="btn btn-primary">Confirm</button>
</div>
</div>
</form>
</div>
</div>
</div>
{% else %}
<!--Render here as per your preferences to indicate the link is invalid-->
Looks like you clicked on an invalid password reset link. Please try again.
{% endif %}
{% endblock content %}