Am I doing something wrong, or is this seriously what the developers expect me to write every time I want to check if two fields are the same?
def c
Firstly, are you seriously complaining about four lines of boiler-plate code? If it really bothers you, create a PasswordForm class that contains that clean logic and sublass it for your own forms as necessary.
Secondly, you don't have to validate unique constraints manually. As you say, the ModelForm does it for you.
Edit after comment
This 'weird syntax' is because checking that two password fields match is a different flow than the normal scheme of things. For a start, you're checking in the main clean method rather than the field-specific clean_myfield. If it had been the latter, you just raise an exception and Django does indeed remove the field data.
So no, this isn't 7 lines on every form - see my note about subclassing - and it certainly isn't 7 lines times multiple fields, because you don't want to do this for any other type of field.