2016-08-11 75 views
1

我正在使用Django 1.9.8,我試圖學習如何使用表單驗證。我正在製作註冊用戶的表單。我有兩個問題,我堅持。在POST數據中丟失了Django表單輸入

  1. 在forms.py文件方法中,無法訪問重新輸入密碼的字段(相反,根本沒有)。當我使用raise Exception(self.cleaned_data.get('password'))查看內容時,會顯示密碼。我也可以查看用戶名和電子郵件。當我做了確認密碼字段一樣,它顯示None編輯 - 這是通過改變forms.py文件使用乾淨()方法

  2. 驗證錯誤不是我的形式顯示在所有解決。如果出現錯誤,重新導向到表單正在工作,但輸入中沒有任何內容供用戶修復,也不顯示錯誤。 編輯 - 通過改變else語句後RegisterForm呼叫解決了form = RegisterForm(request.POST)

這裏是forms.py文件

#forms.py 
class RegisterForm(forms.Form): 
    username = forms.CharField(label="Username", max_length=30, 
           widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'username'})) 
    email = forms.CharField(label="Email", max_length=30, 
           widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'email'})) 
    password = forms.CharField(label="Password", max_length=30, 
           widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'password', 'type' : 'password'})) 
    repassword = forms.CharField(label="RePassword", max_length=30, 
           widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'repassword', 'type' : 'password'})) 

    #Edit - this was changed to the clean() function in the selected answer. 
    def clean_password(self): 
     password1 = self.cleaned_data.get('password') 
     password2 = self.cleaned_data.get('repassword') 
     #raise Exception(self.cleaned_data.get('repassword')) # None is displayed 

     if password1 and password1 != password2: 
      raise forms.ValidationError("Passwords don't match") 
     return self.cleaned_data 

這裏的表單模板

#register.html 

{% if form.errors %} 
    <h2>ERROR!</h2> 
    {% for field in form %} 
     {% for error in field.errors %} 
      <div class="alert alert-error"> 
       <strong>{{ error|escape }}</strong> 
      </div> 
     {% endfor %} 
    {% endfor %} 
{% endif %} 

<form method="post" action="" id="RegisterForm"> 
{% csrf_token %} 
    <p class="bs-component"> 
     <table> 
      <tr> 
       <td>{{ form.username.label_tag }}</td> 
       <td>{{ form.username }}</td> 
      </tr> 
      <tr> 
       <td>{{ form.email.label_tag }}</td> 
       <td>{{ form.email }}</td> 
      </tr> 
      <tr> 
       <td>{{ form.password.label_tag }}</td> 
       <td>{{ form.password }}</td> 
      </tr> 
      <tr> 
       <td>{{ form.repassword.label_tag }}</td> 
       <td>{{ form.repassword }}</td> 
      </tr> 
     </table> 
    </p> 
    <p class="bs-component"> 
     <center> 
      <input class="btn btn-success btn-sm" type="submit" value="Register" /> 
     </center> 
    </p> 
    <input type="hidden" name="next" value="{{ next }}" /> 
</form> 

這裏的查看

#views.py 
class RegisterViewSet(viewsets.ViewSet): 

    #GET requests 
    def register(self,request): 
     return render(request, 'authorization/register.html', {'form': RegisterForm}) 

    #POST requests 
    def create(self,request): 
     form = RegisterForm(request.POST) 
     if form.is_valid(): 
      username = request.POST['username'] 
      email = request.POST['email'] 
      password = request.POST['password'] 
      user = User.objects.create_user(username,email,password) 
      user.save() 
      return HttpResponseRedirect('/users') 
     else: 
      return render(request, 'authorization/register.html', {'form': RegisterForm }) 
      #changed the previous line to the following. This fixed the errors not displaying 
      #return render(request, 'authorization/register.html', {'form': RegisterForm(request.POST) }) 

回答

2

我不是%100肯定爲什麼self.cleaned_data.get('repassword')在該方法中返回None,但clean_password不是執行相互依賴的字段的驗證的正確位置。

docs,你應該在clean()功能進行那種驗證:

views.py

def register(self,request): 
    form = RegisterForm() # Notice `()` at the end 
    return render(request, 'authorization/register.html', {'form': form}) 

forms.py

... 

def clean(self): 
    cleaned_data = super(RegisterForm, self).clean() 

    password1 = cleaned_data.get('password') 
    password2 = cleaned_data.get('repassword') 

    if password1 and password1 != password2: 
     raise forms.ValidationError("Passwords don't match") 

請注意,您不必執行clean_passwordclean_repassword

(如果你認爲你還是要落實clean_password,你必須回到password1從它,而不是self.cleaned_data

您還需要正確呈現形式錯誤,在docs描述。

不要忘記將其添加到您的模板:

{{ form.non_field_errors }} 

至於第二個錯誤,問題是,每個驗證失敗時,你正在返回,而不是無效的一個新的新鮮RegisterForm實例。

您應該更改行create()功能:

return render(request, 'authorization/register.html', {'form': RegisterForm}) 

這樣:

return render(request, 'authorization/register.html', {'form': form}) 
+0

的確認密碼字段現在在forms.py文件訪問和正確驗證,但形式仍然是重定向後空白,並且不顯示錯誤。還有其他建議嗎? – user1852176

+0

您是否在'else'子句中將相關行更改爲'return render(request,'authorization/register.html',{'form':form})''?此外,您應該在此處更新您的模板,例如[docs](https://docs.djangoproject.com/en/1.10/topics/forms/#rendering-fields-manually)中的解釋方式。 – ozgur

+0

是的,我甚至複製並粘貼它是100%確定沒有拼寫錯誤。 – user1852176