Martian4x
Martian4x

Reputation: 57

Why I get "KeyError" exception in django instead of "This field is required" exception on the form validation

I'm new to Django, I have a registration form, Everything works fine If I fill all fields and when I don't fill all the fields. But when I submit a form without a username field I get a "Key Error" instead of "This field is required" Exception since I have declared the field is required on the form class.

forms.py

class UserRegistration(forms.ModelForm):
   first_name = forms.CharField(label='First Name', max_length=50)
   last_name = forms.CharField(label='Last Name', max_length=50)
   username = forms.CharField(label='Username', max_length=50)
   email = forms.EmailField(label='Email', max_length=50)
   password = forms.CharField(label='Password', widget=forms.PasswordInput, max_length=50, validators = [validators.MinLengthValidator(6)])
   password2 = forms.CharField(label='Repeat Password', widget=forms.PasswordInput, max_length=50)

   class Meta:
      model = User
      fields = ('username', 'first_name', 'last_name', 'email', 'password', 'password2')

   def clean_username(self):
      username = self.cleaned_data['username']
      email = self.cleaned_data['email']

      if username and User.objects.filter(username=username).exclude(email=email).count():
         raise forms.ValidationError('This username address is already in use.')
      return username

   def clean_email(self):
      email = self.cleaned_data['email']
      username = self.cleaned_data['username']

      if email and User.objects.filter(email=email).exclude(username=username).count():
         raise forms.ValidationError('This email address is already in use.')
      return email

   def clean_password(self):
      password = self.cleaned_data['password']
      if len(password) < 6:
            raise forms.ValidationError("Password is too short")
      return password

   def clean_password2(self):
      cd = self.cleaned_data
      if cd['password'] != cd['password2']:
         raise forms.ValidationError('Passwords don\'t match.')
      return cd['password2']

views.py

def register(request):
   if request.method == 'POST':
      form = UserRegistration(request.POST)
      if form.is_valid():
         new_user = form.save(commit=False)
         new_user.set_password(
            form.cleaned_data.get('password')
         )
         new_user.save()
         return render(request, 'authapp/register_done.html')
      else:
         return render(request, 'authapp/register.html', {'form':form})
   else:
      form = UserRegistration()

   context = {
      "form": form
   }
   return render(request, 'authapp/register.html', context=context)

Error Traceback Error Page Screenshot

Request Information Post data

Upvotes: 0

Views: 1973

Answers (3)

Gregoire Mulliez
Gregoire Mulliez

Reputation: 1132

5 years latter I was struggeling with this issue, filly stupid mistakes thanks for posting your correction

Upvotes: 0

Martian4x
Martian4x

Reputation: 57

After googling and researching "KeyError" Exception, I have found that the error is caused by accessing a dictionary value with a key 'username' that doesn't exist, hence the KeyError. So it's more of a programming error than Django itself. The solution is to check for the key if it exists before accessing it or use

username = self.cleaned_data.get('username')

instead of

username = self.cleaned_data['username']

according to https://www.journaldev.com/33497/python-keyerror-exception-handling-examples#:~:text=We%20can%20avoid%20KeyError%20by,when%20the%20key%20is%20missing.

Upvotes: 1

Darsh Mamtora
Darsh Mamtora

Reputation: 19

When creating Form, update the username field with required and Null Yes, by default required will be True but it is a constraint for the DB side while the 'null' field is used when any widget is must from UI side

username = forms.CharField(label='Username', max_length=50,required=True,null=False)

And about error you got : username validator is saving empty name so empty data is accessed and used in email validation

Upvotes: 0

Related Questions