AttributeError: 'PasswordReset' object has no attribute 'cleaned_data'

AttributeError: 'PasswordReset' object has no attribute 'cleaned_data'

型号:

class UserInfo(AbstractBaseUser, PermissionsMixin):
    username = models.EmailField(_('邮件'), max_length=50,  default='', unique=True)
    first_name = models.CharField(_('姓'), max_length=50, default='', blank=True, null=False)
    last_name = models.CharField(_('名'), max_length=50, default='')
    mobile = models.CharField(_("手机"), max_length=11, blank=True, null=True)
    img = models.ImageField(_("头像"), upload_to='static/img/users/', default='/static/img/users/100_1.jpg', null=False,
                        blank=False)
    department = models.CharField(_("部门"), max_length=50, default='', blank=True)
    is_active = models.BooleanField(_("有效"), default=True)
    is_staff = models.BooleanField(_("员工"), default=True)
    create_date = models.DateTimeField(_('创建日期'), auto_now_add=True)
    roles = models.ManyToManyField(Role)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['first_name', 'last_name', 'mobile', 'department', 'is_active', 'is_superuser']

    object = UserManager()

    class Meta:
        verbose_name_plural = _("User")

表单扩展自用户信息:

class PasswordReset(forms.ModelForm):
    error_messages = {
        'password_mismatch': _("The two password fields didn't match."),
        'password_incorrect': _("Your old password was entered incorrectly. Please enter it again."),
}
    old_password = forms.CharField(
       label=_("Old password"),
       strip=False,
       widget=forms.PasswordInput(attrs={'autofocus': True, 'class': 'form-control m-input'}),
       required=True,
    )
    new_password1 = forms.CharField(
       label=_("New password"),
       widget=forms.PasswordInput(attrs={'autofocus': True, 'class': 'form-control m-input'}),
       strip=False,
       help_text=password_validation.password_validators_help_text_html(),
       required=True,
)
    new_password2 = forms.CharField(
        label=_("New password confirmation"),
        strip=False,
        widget=forms.PasswordInput(attrs={'autofocus': True, 'class': 'form-control m-input'}),
        required=True,
    )

    class Meta:
        model = UserInfo
        fields = ['username', 'password', 'img', 'first_name', 'last_name']

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

    def clean_old_password(self):
        """
        Validate that the old_password field is correct.
        """
        old_password = self.cleaned_data["old_password"]
        if not self.username.check_password(old_password):
            raise forms.ValidationError(
                self.error_messages['password_incorrect'],
                code='password_incorrect',
            )
        return old_password

def save(self, commit=True):
    password = self.cleaned_data["new_password1"]
    self.username.set_password(password)
    if commit:
        self.username.save()
    return self.username

查看:

class PasswordResetView(View):
    template_name = 'rbac/password.html'

    @method_decorator(login_required)
    def post(self, request, user_id):
        try:
            passwd_object = get_object_or_404(UserInfo, pk=user_id)
            passwd = PasswordReset(request.POST, instance=passwd_object)
            print(passwd.cleaned_data['username'])
            if not passwd.is_valid():
                return render(request, self.template_name, {'passwd': passwd})
            data = passwd.cleaned_data
            if data['new_password1'] == data['old_password']:
                error_message = '新与旧密码一致'
                return render(request, self.template_name, {'passwd': passwd, 'errors': error_message})
            if data['new_password1'] != data['new_password2']:
                error_message = '两次输入不一致'
                return render(request, self.template_name, {'passwd': passwd, 'errors': error_message})
            passwd.save()
            update_session_auth_hash(request, passwd.username)
        except Exception as error_message:
            print(error_message)
            return render(request, self.template_name, {'passwd': passwd, 'errors': error_message})
        return redirect('rbac:user_list')

    @method_decorator(login_required)
    def get(self, request, user_id):
        passwd_object = get_object_or_404(UserInfo, pk=user_id)
        print(dir(passwd_object))
        passwd = PasswordReset(instance=passwd_object, user=passwd_object.username)
        return render(request, self.template_name, {'passwd': passwd})

错误说:

'PasswordReset' object has no attribute 'cleaned_data'
Internal Server Error: /rbac/password/1
Traceback (most recent call last):
  File "/data/www/Opscmdb/rbac/views/account_view.py", line 61, in post
    print(passwd.cleaned_data['username'])
AttributeError: 'PasswordReset' object has no attribute 'cleaned_data

有些错误

在你看来你写道:

passwd = PasswordReset(request.POST, instance=passwd_object)
print(passwd.<b>cleaned_data['username']</b>)
if not passwd.is_valid():
    # ...
    pass

但那时PasswordReset对象还没有.cleaned_data。这仅在您调用 函数 后可用 .is_valid() 函数(并且表单有效)。所以你应该移动 print(..)if 正文中。

稍后在您获取的视图中:

update_session_auth_hash(request, <s><b>passwd.username</b></s>)

为了获取用户名,您应该使用:

update_session_auth_hash(request, <b>data['username']</b>)

最后在get(..)函数中,你写:

@method_decorator(login_required)
def get(self, request, user_id):
    # ...
    <b>passwd = PasswordReset(instance=passwd_object, user=passwd_object.username)</b>
    return render(request, self.template_name, {'passwd': passwd})

你的参数user,根本不存在,所以你应该这样写:

@method_decorator(login_required)
def get(self, request, user_id):
    # ...
    <b>passwd = PasswordReset(instance=passwd_object)</b>
    return render(request, self.template_name, {'passwd': passwd})