Moved model validation from .perform_validation() to .validate()

This commit is contained in:
Marko Tibold 2012-11-27 23:21:12 +01:00
parent e7666014a8
commit f104f74340

View File

@ -221,9 +221,16 @@ class BaseSerializer(Field):
except ValidationError as err: except ValidationError as err:
self._errors[field_name] = self._errors.get(field_name, []) + list(err.messages) self._errors[field_name] = self._errors.get(field_name, []) + list(err.messages)
# We don't run .validate() because field-validation failed and thus `attrs` may not be complete.
# which in turn can cause inconsistent validation errors.
if not self._errors:
try: try:
attrs = self.validate(attrs) attrs = self.validate(attrs)
except ValidationError as err: except ValidationError as err:
if hasattr(err, 'message_dict'):
for field_name, error_messages in err.message_dict.items():
self._errors[field_name] = self._errors.get(field_name, []) + list(error_messages)
elif hasattr(err, 'messages'):
self._errors['non_field_errors'] = err.messages self._errors['non_field_errors'] = err.messages
return attrs return attrs
@ -451,22 +458,15 @@ class ModelSerializer(Serializer):
except KeyError: except KeyError:
return ModelField(model_field=model_field, **kwargs) return ModelField(model_field=model_field, **kwargs)
def from_native(self, data, files): def validate(self, attrs):
restored_object = super(ModelSerializer, self).from_native(data, files) copied_attrs = copy.deepcopy(attrs)
restored_object = self.restore_object(copied_attrs, instance=getattr(self, 'object', None))
if restored_object is None:
return
self.perform_model_validation(restored_object) self.perform_model_validation(restored_object)
return restored_object return attrs
def perform_model_validation(self, restored_object): def perform_model_validation(self, restored_object):
try:
# Call Django's full_clean() which in turn calls: Model.clean_fields(), Model.clean(), Model.validat_unique() # Call Django's full_clean() which in turn calls: Model.clean_fields(), Model.clean(), Model.validat_unique()
restored_object.full_clean(exclude=list(self.opts.exclude)) restored_object.full_clean(exclude=list(self.opts.exclude))
except ValidationError as e:
for field_name, error_messages in e.message_dict.items():
self._errors[field_name] = self._errors.get(field_name, []) + list(error_messages)
def restore_object(self, attrs, instance=None): def restore_object(self, attrs, instance=None):
""" """