django.db.models.Model.clean() should be independent from .clean_fields()
|Reported by:||Tim Molendijk||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 (
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...