程序在调试时运行正常,但在正常运行时崩溃

时间:2015-11-24 15:54:42

标签: python django

我正在使用Django表单在忘记密码时更改用户的密码:

#views.py
def change_forgotten_password(request, key):
    if request.method == 'GET':
        form = ChangePasswordForm()
        return render(request, 'freelancestudent/change_forgotten_password.html', {'form': form})
    else:  # post
        form = ChangePasswordForm(request.POST)
        if form.is_valid():
            user = User.objects.get(forgot_password_key=key)
            user.set_password(form.cleaned_data['password'])
            user.save()
            return redirect('/')

#forms.py
class ChangePasswordForm(forms.Form):
    password = forms.CharField(widget=forms.PasswordInput)
    confirm_password = forms.CharField(widget=forms.PasswordInput)

    def is_valid(self):
        if self.cleaned_data['password'] == self.cleaned_data['confirm_password']:
            return True

当我使用PyCharm的调试器逐步完成代码时,一切都按照我的要求完成;如果密码匹配,则更新所选用户的密码。但是,如果我将其作为(python manage.py runserver)运行,则会显示错误:

AttributeError at /change-forgotten-password/wemnj8vvk37yvikf/

'ChangePasswordForm' object has no attribute 'cleaned_data' 

forms.py的一行,内容为:

if self.cleaned_data['password'] == self.cleaned_data['confirm_password']:
    ...

1 个答案:

答案 0 :(得分:1)

form.cleaned_dataform.is_valid()填充。您忘记在表单中调用超级实现。

def is_valid(self):
    return (
       super(ChangePasswordForm, self).is_valid()
       and self.cleaned_data['password'] == self.cleaned_data['confirm_password']
    )

但是,一般情况下,我不鼓励覆盖is_valid(),而是覆盖form.clean()或类似。正如Brandon所说,django已经在自己的SetPasswordForm中执行了此操作:

def clean_new_password2(self):
    password1 = self.cleaned_data.get('password')
    password2 = self.cleaned_data.get('confirm_password')
    if password1 and password2:
        if password1 != password2:
            raise forms.ValidationError(
                self.error_messages['password_mismatch'],
                code='password_mismatch',
            )
    password_validation.validate_password(password2, self.user)
    return password2

您可能会干,只需重新使用现有的ChangePasswordForm,它接受​​字段'old_password''new_password1''new_password2',因此您可能需要调整模板。