2017-03-15 47 views
0

我能夠成功更新這三種表單中的任何一種。但是,我的問題是,如果更改密碼錶單爲空,則會在其上引發錯誤(如密碼太短,當前密碼不正確等),而不像其他形式,如果我保持不變,則不會發生錯誤。我怎樣才能解決這個問題?我試着設置request.POST or None無濟於事,而且我正在用盡想法。我也不使用{{ form.as_p }},而是逐場進行。這可能是一個問題嗎?多個表單和一個在Django中提交。未提交表單上的錯誤

形式

forms.py

from django.contrib.auth.forms import PasswordChangeForm 

class UserForm(forms.ModelForm): 
    class Meta: 
     model = User 
     fields = ('first_name', 'last_name', 'email') 
     widgets = { 
      'first_name': forms.TextInput(attrs={ 
       'class': 'lnd-user__input', 
       'id': 'first_name', 
       'placeholder': 'First Name'}), 

      'last_name': forms.TextInput(attrs={ 
       'class': 'lnd-user__input', 
       'id': 'last_name', 
       'placeholder': 'Last Name'}), 

      'email': forms.TextInput(attrs={ 
       'class': 'lnd-user__input', 
       'id': 'email', 
       'placeholder': 'Email'}), 

     } 


class UserProfileForm(forms.ModelForm): 
    class Meta: 
     model = UserProfile 
     fields = ('mobile',) 

     widgets = { 
      'mobile': forms.TextInput(attrs={ 
       'class': 'lnd-user__input', 
       'id': 'mobile', 
       'placeholder': 'Phone Number'}) 
     } 


class MyPasswordChangeForm(PasswordChangeForm): 

    old_password = forms.CharField(
     label=("Old password"), 
     required=False, 
     strip=False, 
     widget=forms.PasswordInput(attrs={ 
       'class': 'lnd-user__input', 
       'id': 'new_password2', 
       'type': 'password', 
       'placeholder': 'Old Password'}), 
    ) 

    new_password1 = forms.CharField(
     label=("New password"), 
     required=False, 
     widget=forms.PasswordInput(attrs={ 
       'class': 'lnd-user__input', 
       'id': 'new_password2', 
       'type': 'password', 
       'placeholder': 'Enter new Password'}), 
     strip=False, 
     help_text=password_validation.password_validators_help_text_html(), 
    ) 
    new_password2 = forms.CharField(
     label=("New password confirmation"), 
     required=False, 
     strip=False, 
     widget=forms.PasswordInput(attrs={ 
       'class': 'lnd-user__input', 
       'id': 'new_password2', 
       'type': 'password', 
       'placeholder': 'Repeat new Password'}), 
    ) 

views.py

@login_required(login_url='/accounts/login/') 
def user_settings(request): 
    if request.method == 'GET': 
     user = User.objects.get(id=request.user.id) 
     user_profile = UserProfile.objects.get(user=user) 
     user_form = UserForm(instance=user) 
     user_profile_form = UserProfileForm(instance=user_profile) 
     password_change_form = MyPasswordChangeForm(user) 
     context = { 
      'uform': user_form, 
      'pform': user_profile_form, 
      'pwdform': password_change_form, 
      'user': user} 

     return render(request, 'accounts/user_settings.html', context) 

    if request.method == 'POST': 
     user = User.objects.get(id=request.user.id) 
     user_profile = UserProfile.objects.get(user=user) 

     user_form = UserForm(request.POST or None, instance=user) 
     user_profile_form = UserProfileForm(request.POST or None, instance=user_profile) 
     password_change_form = MyPasswordChangeForm(user, request.POST or None, use_required_attribute=False) 
     print password_change_form.is_valid(), password_change_form.error_messages 
     if request.POST: 
      if user_form.is_valid() is True and user_profile_form.is_valid() is True: 
       user = user_form.save(commit=False) 
       user.save() 
       profile = user_profile_form.save(commit=False) 
       user = User.objects.get(id=request.user.id) 
       profile.user = user 
       profile.save() 

      if password_change_form.is_valid() is True: 
       user_pwd_form = password_change_form.save() 
       update_session_auth_hash(request, user) # Important! 
       user_pwd_form.save() 

      context = { 
       'uform': user_form, 
       'pform': user_profile_form, 
       'pwdform': password_change_form, 
       'user': user, 
      } 

      return render(request, 'accounts/user_settings.html', context) 
+0

看起來這個表格不是強制性的,所以你應該檢查表單是否有任何數據,然後驗證它。或者使用其他方式來確定是否也提交了表單中的數據。 – Rohan

回答

0

看來你不想密碼錶單驗證失敗,除非一些字段被填充但不他們全部。而通過使所需的字段django將失敗驗證,如果有留下空白。所以,你應該做的是讓所有的表單字段required=False,然後添加一個clean方法您的密碼形式,這樣的事情:

from django.core.exceptions import ValidationError 

def clean(self): 
    data = super(MyPasswordChangeForm, self).clean() 

    # if django field validation already failed, don't do any more validation 
    # because the field values we need to check might not be present. 
    if self.errors: 
     return data 

    # you could do this a lot of different ways, some of them simpler probably... 
    fields = ('old_password', 'new_password1', 'new_password2') 
    for fn in fields: 
     # if any field contains data 
     if data[fn]: 
      for fn in fields: 
       # if any field does not contain data 
       if not data[fn]: 
        raise ValidationError("All fields must be filled in.") 
      break 
    return data 

這樣一來,如果用戶沒有在任何字段填寫changepassword表單,它不會失敗驗證。然後,如果你想看到的人是否真正想改變自己的密碼,你必須做一些事情在你看來這樣的:

if form.cleaned_data['new_password1']: 
    # put code here to change the users password 

注意,我所以它可能並不完美沒有測試該代碼但它應該相當接近你所需要的。

在Django窗體中,clean方法是他們爲您提供的表單驗證所涉及的多個字段的鉤子。例如,如果兩個數字輸入必須加起來第三個數字,那就是您的位置會檢查。如果表單輸入有任何問題,請提出ValidationError異常,Django將在表單上顯示驗證錯誤。