mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-02 11:30:12 +03:00
Merge 301ab5f88e
into 304b193efe
This commit is contained in:
commit
dac5d45122
|
@ -231,6 +231,50 @@ class BaseSerializer(WritableField):
|
|||
|
||||
return ret
|
||||
|
||||
#####
|
||||
# Methods to insert an error in the errors dict.
|
||||
|
||||
def get_non_field_error_key(self):
|
||||
"""
|
||||
Return the key under which to store non field related errors.
|
||||
"""
|
||||
return "non_field_errors"
|
||||
|
||||
def format_full_clean_errors(self, errors, instance, full_clean_error):
|
||||
"""
|
||||
Handling formatting errors generated by Django's full_clean method.
|
||||
"""
|
||||
return full_clean_error.message_dict
|
||||
|
||||
def format_non_field_error(self, errors, data, non_field_error):
|
||||
"""
|
||||
Handles formatting non field related errors.
|
||||
"""
|
||||
current_list = errors.setdefault(self.get_non_field_error_key(), [])
|
||||
if isinstance(non_field_error, list):
|
||||
current_list.extend(non_field_error)
|
||||
else:
|
||||
current_list.append(non_field_error)
|
||||
return errors
|
||||
|
||||
def format_field_error(self, errors, data, field_name, field_error):
|
||||
"""
|
||||
Handles formatting field specific errors.
|
||||
"""
|
||||
current_list = errors.setdefault(field_name, [])
|
||||
if isinstance(field_error, list):
|
||||
current_list.extend(field_error)
|
||||
else:
|
||||
current_list.append(field_error)
|
||||
return errors
|
||||
|
||||
def format_many_error(self, errors, data, data_errors):
|
||||
"""
|
||||
Handles formatting bulk operations errors.
|
||||
"""
|
||||
errors.append(data_errors)
|
||||
return errors
|
||||
|
||||
#####
|
||||
# Methods to convert or revert from objects <--> primitive representations.
|
||||
|
||||
|
@ -248,7 +292,7 @@ class BaseSerializer(WritableField):
|
|||
reverted_data = {}
|
||||
|
||||
if data is not None and not isinstance(data, dict):
|
||||
self._errors['non_field_errors'] = ['Invalid data']
|
||||
self._errors = self.format_non_field_error(self._errors, None, 'Invalid data')
|
||||
return None
|
||||
|
||||
for field_name, field in self.fields.items():
|
||||
|
@ -256,11 +300,11 @@ class BaseSerializer(WritableField):
|
|||
try:
|
||||
field.field_from_native(data, files, field_name, reverted_data)
|
||||
except ValidationError as err:
|
||||
self._errors[field_name] = list(err.messages)
|
||||
self._errors = self.format_field_error(self._errors, data, field_name, list(err.messages))
|
||||
|
||||
return reverted_data
|
||||
|
||||
def perform_validation(self, attrs):
|
||||
def perform_validation(self, attrs, data):
|
||||
"""
|
||||
Run `validate_<fieldname>()` and `validate()` methods on the serializer
|
||||
"""
|
||||
|
@ -276,7 +320,7 @@ class BaseSerializer(WritableField):
|
|||
if validate_method:
|
||||
attrs = validate_method(attrs, source)
|
||||
except ValidationError as err:
|
||||
self._errors[field_name] = self._errors.get(field_name, []) + list(err.messages)
|
||||
self._errors = self.format_field_error(self._errors, data, field_name, list(err.messages))
|
||||
|
||||
# If there are already errors, we don't run .validate() because
|
||||
# field-validation failed and thus `attrs` may not be complete.
|
||||
|
@ -287,9 +331,9 @@ class BaseSerializer(WritableField):
|
|||
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)
|
||||
self._errors = self.format_field_error(self._errors, data, field_name, list(error_messages))
|
||||
elif hasattr(err, 'messages'):
|
||||
self._errors['non_field_errors'] = err.messages
|
||||
self._errors = self.format_non_field_error(self._errors, data, err.messages)
|
||||
|
||||
return attrs
|
||||
|
||||
|
@ -340,9 +384,9 @@ class BaseSerializer(WritableField):
|
|||
if data is not None or files is not None:
|
||||
attrs = self.restore_fields(data, files)
|
||||
if attrs is not None:
|
||||
attrs = self.perform_validation(attrs)
|
||||
attrs = self.perform_validation(attrs, data)
|
||||
else:
|
||||
self._errors['non_field_errors'] = ['No input provided']
|
||||
self._errors = self.format_non_field_error(self._errors, None, 'No input provided')
|
||||
|
||||
if not self._errors:
|
||||
return self.restore_object(attrs, instance=getattr(self, 'object', None))
|
||||
|
@ -491,18 +535,18 @@ class BaseSerializer(WritableField):
|
|||
self.object = identity_to_objects.pop(identity, None)
|
||||
if self.object is None and not self.allow_add_remove:
|
||||
ret.append(None)
|
||||
errors.append({'non_field_errors': ['Cannot create a new item, only existing items may be updated.']})
|
||||
errors.append(self.format_non_field_error({}, item, 'Cannot create a new item, only existing items may be updated.'))
|
||||
continue
|
||||
|
||||
ret.append(self.from_native(item, None))
|
||||
errors.append(self._errors)
|
||||
self.format_many_error(errors, item, self._errors)
|
||||
|
||||
if update and self.allow_add_remove:
|
||||
ret._deleted = identity_to_objects.values()
|
||||
|
||||
self._errors = any(errors) and errors or []
|
||||
else:
|
||||
self._errors = {'non_field_errors': ['Expected a list of items.']}
|
||||
self._errors = self.format_non_field_error({}, None, 'Expected a list of items.')
|
||||
else:
|
||||
ret = self.from_native(data, files)
|
||||
|
||||
|
@ -857,7 +901,7 @@ class ModelSerializer(Serializer):
|
|||
try:
|
||||
instance.full_clean(exclude=self.get_validation_exclusions())
|
||||
except ValidationError as err:
|
||||
self._errors = err.message_dict
|
||||
self._errors = self.format_full_clean_errors(self._errors, instance, err)
|
||||
return None
|
||||
return instance
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user