JPC*_*JPC 14 django django-models django-forms
当我尝试提交表单时,我收到了'密码'的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'
Run Code Online (Sandbox Code Playgroud)
观点:
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)
Run Code Online (Sandbox Code Playgroud)
形式:
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')
Run Code Online (Sandbox Code Playgroud)
Cau*_*ons 17
根据我自己的经验,我发现如果你想在多个字段中进行一些验证,即使它们被标记为required = True,当你覆盖clean()表单中的方法时,如果在提交时未填写要验证的字段它和你试图访问它们,因为cleaned_data["field_name"]你的代码会爆炸KeyError.要避免这种情况,只需通过get()字典方法访问cleaning_data中的字段,然后检查是否为None,或者传递默认值.作为推论:
my_field = cleaned_data.get("field_name") # This is safe and it will work! :)
my_filed = cleaned_data["field_name"] # This will crash when the field was not filled! :(
Run Code Online (Sandbox Code Playgroud)
我希望这有助于其他人,因为这个愚蠢的事情,我失去了很多时间!
Man*_*dan 10
啊哈!您看到的验证错误消息实际上不是验证错误消息.让我解释.使用时渲染模型表单实例as_p,它以下列方式呈现每个字段:
<p><label ...>fieldname</label> <input ... name="fieldname" /> HELP TEXT IF ANY</p>
Run Code Online (Sandbox Code Playgroud)
Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters您在字段右侧看到的字符串只是帮助文本.此帮助文本取自模型定义 - 您可以通过访问django/contrib/auth/models.py和检查User类的定义来验证这一点.
覆盖该username字段时,您将省略任何帮助文本.当然,"错误"消失了.
为了验证这一理论,请在您的main方法中执行以下操作.
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})
Run Code Online (Sandbox Code Playgroud)
更新
if self.cleaned_data['cpassword']!=self.cleaned_data['password']:
Run Code Online (Sandbox Code Playgroud)
这条线可能会导致故障,当用户不提供一个或两个的password和cpassword.例如,从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'
Run Code Online (Sandbox Code Playgroud)
更改表单的clean方法以确保在比较之前存在两个值.像这样的东西:
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")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13372 次 |
| 最近记录: |