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

Tags: , , ,



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

Answer

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.



Source: stackoverflow