2016-01-05 26 views
0

我已经制作了一个“编辑个人资料”表单,您可以在这里进行一个非常经典的操作:更改密码。验证设计:表单还是视图?

因此我有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

Django实际上有一个内置的表单,用于更改可以引用的用户密码。请参阅https://github.com/django/django/blob/master/django/contrib/auth/forms.py上的SetPasswordFormPasswordChangeForm

不要在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 

密码更改操作应该以单独的方法在窗体中完成。下面是你需要的视图代码示例:

class MyView(TemplateView): 

    def post(self, request, *args, **kwargs): 
     form = MyForm(user=request.user, data=request.POST) 
     if form.is_valid(): 
      form.save() # password updated 
      return redirect(<somehwere>) 

     # the password change has failed form validation 
     return self.render_to_response({}) 

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

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

0

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

如果您确实需要对自己的观点和形式进行调整,我认为可以在视图form_valid()方法中更改密码。

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

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