2013-04-06 77 views
0

我有一个注册,让用户注册,我有困难解决它。Django KeyError at/register/

问题出在用户提交单个字段而不是整个表单时,例如电子邮件。我得到这个错误

KeyError at /register/ 

password 
Request Method:  POST 
Request URL: http://127.0.0.1:8000/register/ 
File "C:\Python26\Lib\site-packages\django\forms\forms.py" in _get_errors 
    115.    self.full_clean() 
File "C:\Python26\Lib\site-packages\django\forms\forms.py" in full_clean 
    271.   self._clean_form() 
File "C:\Python26\Lib\site-packages\django\forms\forms.py" in _clean_form 
    299.    self.cleaned_data = self.clean() 
File "C:\o\17\mysite\pet\forms.py" in clean 
    31.  if self.cleaned_data['password'] != self.cleaned_data['password1']: 

Exception Type: KeyError at /register/ 
Exception Value: password 

我试图用if修复这个解决方案。如果用户提交了用户名或其他必填字段,则处理该表单,否则重新显示原始表单。

但我仍然得到相同的错误。

这是我的编辑views.py (在页面的底部是我原来的RegistrationForm)

def PetRegistration(request): 
    if request.user.is_authenticated(): 
     return HttpResponseRedirect(reverse('world:HappyLand')) 

    if request.method =='POST': 
     form = UserRegistration(request.POST) 
    if form.is_valid(): 
     username = form.cleaned_data['username'] 
     if username: 
      email=form.cleaned_data['email'] 
      if email: 
       password=form.cleaned_data['password'] 
       if password: 
        user = User.objects.create_user(
      username=form.cleaned_data['username'], 
      email=form.cleaned_data['email'], 
      password=form.cleaned_data['password'] 
      ) 
        user.is_active = True 
        user.first_name = form.cleaned_data['name'] 
        user.save() 

        person = authenticate(
      username=form.cleaned_data['username'], 
      password=form.cleaned_data['password'] 
      ) 

        Person.objects.create(user_id=user.id, 
        name=form.cleaned_data['name'],birthday=form.cleaned_data['birthday']) 

        login(request, person) 
        return HttpResponseRedirect(reverse('world:HappyLand')) 

return render(request, 'register.html', {'form': UserRegistration()}) 

我怎样才能解决这个错误还我怎么会在显示错误消息用户未填写的其他字段,如“错误丢失字段,请填写此字段”。

def PetRegistration(request): 
if request.user.is_authenticated(): 
    return HttpResponseRedirect(reverse('world:HappyLand')) 

if request.method =='POST': 
    form = UserRegistration(request.POST) 
    if form.is_valid(): 
     user = User.objects.create_user(
      username=form.cleaned_data['username'], 
      email=form.cleaned_data['email'], 
      password=form.cleaned_data['password'] 
      ) 
     user.is_active = True 
     user.first_name = form.cleaned_data['name'] 
     user.save() 

     person = authenticate(
      username=form.cleaned_data['username'], 
      password=form.cleaned_data['password'] 
      ) 

     Person.objects.create(user_id=user.id, 
      name=form.cleaned_data['name'],birthday=form.cleaned_data['birthday']) 

     login(request, person) 
     return HttpResponseRedirect(reverse('world:HappyLand')) 

return render(request, 'register.html', {'form': UserRegistration()}) 

我forms.py

class UserRegistration(forms.Form): 
    username = forms.CharField() 
    name = forms.CharField() 
    email = forms.EmailField() 
    birthday = forms.DateField(widget=extras.SelectDateWidget(years=range(1950, 2012))) 

    password = forms.CharField(
     widget=forms.PasswordInput(render_value=False) 
     ) 
    password1 = forms.CharField(
     label=(u'Verify Password'), 
     widget = forms.PasswordInput(render_value=False) 
     ) 

    def clean_username(self): 
     username = self.cleaned_data['username'] 
     try: 
      User.objects.get(username=username) 
     except User.DoesNotExist: 
      return username 
     raise forms.ValidationError(
      "That user is already taken , please select another ") 

    def clean(self): 
     if self.cleaned_data['password'] != self.cleaned_data['password1']: 
      raise forms.ValidationError("The password does not match ") 
     return self.cleaned_data 

我的models.py

class Person(models.Model): 
    user = models.ForeignKey(User) 
    name = models.CharField(max_length=100, blank=True) 
    birthday = models.DateField(blank=True,null=True) 
    def __unicode__(self): 
     return self.name 

回答

5

问题是在你clean()。在clean()中,您尝试访问表单的cleaned_data上的字段passwordpassword将只在cleaned_data上可用,如果用户填写了该字段。因此,在尝试访问它之前,您必须检查password是否存在于cleaned_data中。

改变你clean()

def clean(self): 
    if 'password' in self.cleaned_data and 'password1' in self.cleaned_data and self.cleaned_data['password'] != self.cleaned_data['password1']: 
     raise forms.ValidationError("The password does not match ") 
    return self.cleaned_data 

可以提供表单域关键字参数error_messages用于显示类似错误消息“缺少字段,请填写此场”。

class SomeForm(forms.Form): 
    name = forms.CharField(error_messages={'required':'Error Missing Field , Please Fill this Field'}) 

在您看来有一个错误。

is_valid()在表单上填充错误,但必须将相同的表单实例发送到模板,以便可以访问表单字段上的错误。

但在您看来,您只有一个致电render()的调用,即使在发布请求中的表单无效时也会被调用。在此render()中,您正在创建一个新的窗体实例。所以,你发送给模板的这个新表单不会有任何错误。

因此,使得轻微修改您的观点:在你看来

def PetRegistration(request): 
    if request.user.is_authenticated(): 
    return HttpResponseRedirect(reverse('world:HappyLand')) 

    form = UserRegistration() #This will be used in GET request 
    if request.method =='POST': 
     form = UserRegistration(request.POST) #This will be used in POST request 
     if form.is_valid(): 
      user = User.objects.create_user(
       username=form.cleaned_data['username'], 
       email=form.cleaned_data['email'], 
       password=form.cleaned_data['password'] 
      ) 
      user.is_active = True 
      user.first_name = form.cleaned_data['name'] 
      user.save() 

      person = authenticate(
       username=form.cleaned_data['username'], 
       password=form.cleaned_data['password'] 
      ) 

      Person.objects.create(user_id=user.id, 
       name=form.cleaned_data['name'],birthday=form.cleaned_data['birthday']) 

      login(request, person) 
      return HttpResponseRedirect(reverse('world:HappyLand')) 

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

通知,我如果POST请求,检查前加入form=UserRegistration(),并在两个地方,我们都实例UserRegistration已经添加了评论。然后在render(),你应该发送这个form

然后你的{{form.username.errors}}将工作。

+0

错误信息不起作用。 {{form.username.errors}} {{form.username}} – donkeyboy72 2013-04-14 23:45:32

+0

编辑我的答案,以便{{form.username.errors}}工作。 – 2013-04-15 16:37:53

+0

噢好吧,我明白了它为什么有效。谢谢你 – donkeyboy72 2013-04-16 07:54:29

1

我只是修改你的forms.py

class UserRegistration(forms.Form): 
    username = forms.CharField() 
    name = forms.CharField() 
    email = forms.EmailField() 
    birthday = forms.DateField(widget=extras.SelectDateWidget(years=range(1950, 2012))) 
    password = forms.CharField(
     widget=forms.PasswordInput(render_value=False) 
     ) 
    password1 = forms.CharField(
     label=(u'Verify Password'), 
     widget = forms.PasswordInput(render_value=False) 
     ) 

    def clean(self): 
     cleaned_data = super(UserRegistration, self).clean() 
     username = cleaned_data.get("username") 
     password = cleaned_data.get("password") 
     password1 = cleaned_data.get("password1") 

     #check if username exist 
     user = User.objects.filter(username=username) 
     if user: 
      raise forms.ValidationError(
       "That user is already taken , please select another ") 

     #check password 
     if password != password1: 
      raise forms.ValidationError(
       "Your current and confirm password do not match.") 

     return cleaned_data 
+0

您的清洁方法不正确, – catherine 2013-04-06 04:07:46

+0

尝试'form.errors'显示错误 – catherine 2013-04-06 04:08:32

+0

'后,如果form.is_valid()''创建然后else'下的其他调用'form.errors' – catherine 2013-04-06 04:16:40