2016-08-11 81 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

相关问题