I’ve got a relatively standard RegistrationForm that looks like this:
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='')
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”)
I’ve tried the following two options in my clean() method (I’ll use the password and password_repeat fields as examples):
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.")
The first option returns:
KeyError at /homepage/
‘password’
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.")
The second option returns:
UnboundLocalError at /homepage/
local variable ‘password’ referenced before assignment
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).
You can use the
requiredproperty available for all Field types, which automatically does this type of validation. So your code would look like:Note: I think you can leave out those
initial = ''parameters as well, as shown above.I’m actually not sure why you’re getting the errors you mentioned in your question, perhaps you could post the relevant code from your
views.py? It could be because you need to returncleaned_dataat the end of anycleanmethod you implement.I would also just say that your use of the
cleanmethod is not quite right. If you refer to this page of the documentation on form and field validation you see that to validate a single field you use the specificclean_<fieldname>method e.g.clean_password_repeat. Using thecleanmethod is appropriate when validation involves multiple field simultaneously, one example of this you may like to use is checking the inputs for the two password fields match.Note: Code is not tested.
I hope this was helpful!