title: Django: How to raise an exception when a user submits an unfinished form?
body: <p>I've got a relatively standard RegistrationForm that looks like this:</p>
  
  <pre><code>class RegisterForm(forms.Form):
      username = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'username'}), initial='')
      email = forms.EmailField(widget=forms.TextInput(attrs={'placeholder': 'email'}), initial='')
      password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'password'}), initial='')
      password_repeat = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'retype password'}), initial='')
  </code></pre>
  
  <p><em><strong>How could I create a clean method that returns an error when a user forgets to fill in one or more fields? (ie. "You forgot to fill in the email field")</em></strong> </p>
  
  <p>I've tried the following two options in my clean() method (I'll use the password and password_repeat fields as examples):</p>
  
  <pre><code>password = self.cleaned_data['password']
  password_repeat = self.cleaned_data['password_repeat']
  # initial values are set to '' for all fields, see above.
  if password == '':
      raise forms.ValidationError("You forgot to type in a password.")
  elif password_repeat == '':
          raise forms.ValidationError("You forgot to retype your password.")
  </code></pre>
  
  <p><strong>The first option returns:</strong></p>
  
  <p>KeyError at /homepage/</p>
  
  <p>'password'</p>
  
  <hr>
  
  <pre><code>try:
      password = self.cleaned_data['password']
      password_repeat = self.cleaned_data['password_repeat']
  except KeyError(password):
      raise forms.ValidationError("You forgot to fill in the password field.")
  </code></pre>
  
  <p><strong>The second option returns:</strong> </p>
  
  <p>UnboundLocalError at /homepage/</p>
  
  <p>local variable 'password' referenced before assignment</p>
  
  <hr>
  
  <p>Bonus points if you can provide a solution that allows for the remaining fields to be checked as well (so that I can return an form bound to the data the user successfully submitted).</p>