2016-01-05 68 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()方法。此方法的目的是檢查表單是否有效。你很少需要重寫它。