【问题标题】:Django PasswordResetConfirmView password reset failed not workingDjango PasswordResetConfirmView 密码重置失败不起作用
【发布时间】:2021-03-30 03:25:16
【问题描述】:

当使用 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 %}

【问题讨论】:

  • 请将reset_password.html 模板和UserAccountPasswordResetForm 表格添加到您的问题中。
  • 添加到哪里?我应该添加额外的上下文吗?如果我应该在那里添加,那么我应该添加哪些相应的键?
  • 你知道为什么密码失败不呈现吗?
  • 我添加了所有文件
  • 这里虽然不需要 HTML 文件..如果令牌无效,则不会呈现此 HTML。失败消息应该呈现

标签: python-3.x django django-views django-3.0


【解决方案1】:

extra_context 中传递一个模板名称没有。如果令牌无效,PasswordResetConfirmViewform 设置为None 并将其传递给上下文。您尝试使该表单出现错误。相反,您应该检查在上下文中传递的变量 validlink 以指示链接是否正确并正确呈现:

{% 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 %}

【讨论】:

    猜你喜欢
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    • 2016-04-30
    • 2015-08-26
    相关资源
    最近更新 更多