django.db.models.Model.clean() should be independent from .clean_fields()
|Reported by:||timmolendijk||Owned by:||nobody|
|Component:||Database layer (models, ORM)||Version:||master|
|Severity:||Keywords:||model validation clean|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
# Form.clean() is run even if other validation fails, so do the # same with Model.clean() for consistency.
This behavior can be surprisingly annoying. Assume a model Car with a foreign key field (null=False) named owner. Now assume one of the restrictions on Car is that owner.gender == 'm' (yeah ridiculous, I know ;)). One would think that a model clean method as follows would do the job:
def clean(self): if self.owner.gender != 'm': raise ValidationError("Women are not allowed to own cars!")
BUT, this will crash the system every time you try to save a car instance that has no owner assigned. One would say that clean() does not have to worry about the requirement that an owner is obligatory, because that's what clean_fields() is for, right? WRONG, because clean() will always run, regardless of the success of clean_fields(). And running clean() will result in an ObjectDoesNotExist error because self.owner does not have a value.
The consequence is that clean() must anticipate on all potential validation errors in clean_fields(). Bye bye separation of concerns...