验证设计:表单还是视图?

时间:2016-01-05 17:31:01

标签: django django-forms django-views

我已经制作了一个"编辑个人资料"在哪里可以形成非常经典的东西:更改密码。

因此我有3个字段:旧密码,新密码和重新输入新密码。

问题在于设计。 我首先检查所有输入的内容是否正确,格式为clean方法

def clean(self):
    old = self.cleaned_data.get('old_password')
    new1 = self.cleaned_data.get('new_password1')
    new2 = self.cleaned_data.get('new_password2')
    if old:
        if not new1:
            raise ValidationError(_(u'New password missing'))
        if not new2:
            raise ValidationError(_(u'New password missing'))
        if new1 != new2:
            raise ValidationError(_(u"The new password "
                                    u"is not the same twice"))
    return super(ProfileForm, self).clean()

从我的表单中,除非我破解,否则我无法访问当前登录的用户。 我的问题是关于设计:最好是破解表单代码,然后在表单 is_valid() 中更改密码,或者更好在视图 form_valid() 方法中进行操作?

2 个答案:

答案 0 :(得分:2)

Django实际上有一个内置的表单,用于更改您可以引用的用户密码。请参阅https://github.com/django/django/blob/master/django/contrib/auth/forms.py上的substring(eval(eval(incidentSourceList[. != ""], 'concat(., ", ")'), ".."), 0, string-length(eval(eval(incidentSourceList[. != ""], 'concat(., ", ")'), "..")) - 1) SetPasswordForm

不要在PasswordChangeForm方法中更改密码,它仅用于验证。您可以覆盖表单is_valid()以取得用户,并使用__init__方法更改密码。

save

密码更改操作应以单独的方式在表单中完成。以下是您需要的视图代码示例:

class MyForm(forms.Form):

    def __init__(self, user, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.user =  user

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

要回答您的问题,最好更改表单中的密码,而不是视图。在Django中,以表格形式执行数据操作(例如ModelForm.save())是一种相当常见的模式,并且大多数Django自己的代码也会在表单中更改模型数据。

这分离了从视图中更改模型数据的逻辑,并使单元测试和推理变得更加容易(例如,您不需要依赖视图来测试更改密码操作)。

答案 1 :(得分:0)

首先,Django附带viewform来更改密码],如果可能,您应该使用它们。

如果您确实需要修改自己的视图和表单,我认为可以在视图form_valid()方法中更改密码。

您可以将设置新密码的代码移动到表单上的方法,然后在form_valid方法中调用此方法。这种方法的缺点是您必须覆盖表单的__init__方法和视图的get_form_kwargs方法以将用户传递给表单,这使其更复杂。优点是您已在视图中封装了该功能。

请勿覆盖表单的is_valid()方法。此方法的目的是检查表单是否有效。你很少需要覆盖它。