Search code examples
pythondjangodjango-modelsdjango-formsmixins

Create mixin in forms to check passwords


I have some models of Patient, Doctors and so on, then I use them to create forms based on ModelForm with some additional fields:

class CreateClinicForm(forms.ModelForm):
    email = forms.EmailField(required=True)
    name = forms.CharField(max_length=200, required=True)
    specialties = forms.CharField(max_length=100, required=True)
    phone = forms.IntegerField(required=True)

    class Meta:
        model = Clinic
        fields = ('name', 'specialties')

And I have password checking in these forms, so it would be nice to use mixin. I have tried to create this one, but it doesn't work.

class PasswordMatchMixin(object):
    password = forms.CharField(max_length=32, required=True)
    password_confirm = forms.CharField(max_length=32, required=True)

def clean_password_confirm(self):
    password = self.cleaned_data.get('password')
    password_confirm = self.cleaned_data.get('password_confirm')
    if password and password != password_confirm:
        raise ValidationError(_("Passwords don't match"))
    return self.password_confirm

Of course, after that I added it to my forms like this :

class CreateDoctorForm(PasswordMatchMixin, forms.ModelForm) : ...

Some thoughts or ideas?


Solution

  • If you are cleaning fields that rely on each other, you should override clean instead of clean_password.

    class PasswordMatchMixin(object):
        password = forms.CharField(max_length=32, required=True)
        password_confirm = forms.CharField(max_length=32, required=True)
    
        def clean(self):
            cleaned_data = super(PasswordMatchMixin, self).clean()
            password = cleaned_data.get('password')
            password_confirm = cleaned_data.get('password_confirm')
            if password and password != password_confirm:
                raise ValidationError(_("Passwords don't match"))
            return cleaned_data
    

    If you override clean in your form, remember to call super() so that the PasswordMatchMixin.clean method is called.