views:

26

answers:

2

I have a user registration form that has a "password" and "confirm password" field. When I add "min_length" to my password field and then run the submitted data through my custom clean_confirm_password method, it gives a "Key Error / Password" error.

This occurs when the password field is less than 5 characters, whether the confirm_password field matches or not.

I have tried adding "min_length" to "confirm_password," but still get the same error.

Everything works fine when I remove "min_length" totally.

Any help is appreciated!

My forms.py file:

class NewUser(forms.Form):
    email = forms.EmailField(max_length=75)
    first_name = forms.CharField(max_length=45)
    last_name = forms.CharField(max_length=45)
    password = forms.CharField(min_length=5, max_length=30, widget=forms.PasswordInput(render_value=False))
    confirm_password = forms.CharField(max_length=30, widget=forms.PasswordInput(render_value=False))

    def clean_confirm_password(self):
        confirm_password = self.cleaned_data['confirm_password']
        original_password = self.cleaned_data['password']
        if original_password != confirm_password:
            raise forms.ValidationError("Password doesn't match")

        return confirm_password
A: 

When you access self.cleaned_data, the form validates all of its fields, which would cause the password field to be validated against its min_length argument.

Joseph Spiros
Sorry. I see now my question wasn't entirely clear. I want the password field to validate as you described, but instead of coming back with my error message, it gives the Key Error. So if I enter 3 digits in the password field, and any password in the confirm password field (matching or not), instead of giving me the "Not enough characters" error, it throws a Key Error.
Ben S
+1  A: 

When you submit a password with fewer than 5 characters, it fails the min_length validation so password is not in your form's cleaned_data dictionary. When you try to access the missing key, you get a KeyError.

Instead, you should try:

original_password = self.cleaned_data.get('password', '')

which will return '' if the password is too short.

As an aside, a clean_myfieldname method should only rely on one field. If you want to clean and validate fields that rely on each other, use the clean method for this (see the django docs).

Alasdair
This worked like a champ! Also, thanks for pointing out the `clean` method. I've made changes accordingly.
Ben S