当我尝试提交表单时,我会收到一个“密码”的KeyError.
跟踪:
Request Method: POST Request URL: http://localhost:8000/register/ Django Version: 1.2.1 Python Version: 2.7.0 Installed Applications: ['django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','djangoproject1.authentication'] Installed Middleware: ('django.middleware.common.CommonMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware') Traceback: File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response 100. response = callback(request,*callback_args,**callback_kwargs) File "C:\Users\jec23\My Java Projects\djangoproject1\src\djangoproject1\authentication\views.py" in register 20. if rf.is_valid() and pf.is_valid(): File "C:\Python27\lib\site-packages\django\forms\forms.py" in is_valid 121. return self.is_bound and not bool(self.errors) File "C:\Python27\lib\site-packages\django\forms\forms.py" in _get_errors 112. self.full_clean() File "C:\Python27\lib\site-packages\django\forms\forms.py" in full_clean 268. self._clean_form() File "C:\Python27\lib\site-packages\django\forms\forms.py" in _clean_form 296. self.cleaned_data = self.clean() File "C:\Users\jec23\My Java Projects\djangoproject1\src\djangoproject1\authentication\forms.py" in clean 16. if self.cleaned_data['cpassword']!=self.cleaned_data['password']: Exception Type: KeyError at /register/ Exception Value: 'password'
观点:
def register(request): if request.method == 'POST': rf = forms.RegisterForm(request.POST) pf = forms.ProfileForm(request.POST) if rf.is_valid() and pf.is_valid(): newuser = User(username=rf.cleaned_data['username'],email=rf.cleaned_data['email']) newuser.set_password(rf.cleaned_data['password']) newuser.save() profile = pf.save(commit=False) profile.user = newuser profile.save() return HttpResponseRedirect("/register-success/") else: return render_to_response("authentication/index.html",{'form1': rf,'form2':pf}) else: return main(request)
形式:
class RegisterForm(forms.Form): username = forms.CharField(min_length=6,max_length=15) password = forms.CharField(min_length=6,max_length=15,widget = forms.PasswordInput()) cpassword = forms.CharField(label='Confirm Password',widget = forms.PasswordInput()) email = forms.EmailField(label='E-mail Address') def clean(self): if self.cleaned_data['cpassword']!=self.cleaned_data['password']: raise forms.ValidationError("Passwords don't match") return self.cleaned_data class ProfileForm(forms.ModelForm): phonenumber = forms.CharField(label='Phone Number') class Meta: model = UserProfile exclude = ('user')
解决方法
啊哈!您看到的验证错误消息实际上不是验证错误消息.让我解释.当使用as_p渲染模型窗体实例时,它将以下列方式呈现每个字段:
<p><label ...>fieldname</label> <input ... name="fieldname" /> HELP TEXT IF ANY</p>
字符串必需. 30个字符以内.您在字段右侧看到的字母,数字和@ /./ / – / _字符只不过是帮助文本.这个帮助文本取自模型定义 – 您可以通过访问django / contrib / auth / models.py并检查User类的定义来验证这一点.
当您覆盖用户名字段时,您将省略任何帮助文本.当然,“错误”消失了.
为了验证这个理论,在你的主要方法中做以下几点.
def main(request): uf = forms.UserForm() upf = forms.UserProfileForm() print "User form is bound:%s errors:%s" % (uf.is_bound,uf.errors) return render_to_response("authentication/index.html",{'form1': uf,'form2':upf})
更新
if self.cleaned_data['cpassword']!=self.cleaned_data['password']:
当用户不提供一个或两个密码和密码时,此行可能会导致麻烦.例如,尝试从Django shell:
>>> data = dict(username = 'admin',cpassword = 'foo',email='admin@bar.com') >>> f = RegisterForm(data) >>> f.is_bound True >>> f.is_valid() Traceback (most recent call last): ... File "<pyshell#2>",line 8,in clean if self.cleaned_data['cpassword']!=self.cleaned_data['password']: KeyError: 'password'
更改表单的清洁方法,以确保在比较之前两个值都存在.这样的东西
def clean(self): password = self.cleaned_data.get('password',None) cpassword = self.cleaned_data.get('cpassword',None) if password and cpassword and (password == cpassword): return self.cleaned_data else: raise forms.ValidationError("Passwords don't match")