diff --git a/rest_framework/compound_fields.py b/rest_framework/compound_fields.py index fce6eb84f..1766ccae9 100644 --- a/rest_framework/compound_fields.py +++ b/rest_framework/compound_fields.py @@ -2,7 +2,11 @@ Compound fields for processing values that are lists and dicts of values described by embedded fields. """ +from django.core.exceptions import ValidationError +from django.utils.translation import ugettext_lazy as _ + from .fields import WritableField +from rest_framework.compat import six class ListField(WritableField): @@ -11,6 +15,10 @@ class ListField(WritableField): be another field type (e.g., CharField) or a serializer. """ + default_error_messages = { + 'invalid_type': _('%(value)s is not a list.'), + } + def __init__(self, item_field=None, *args, **kwargs): super(ListField, self).__init__(*args, **kwargs) self.item_field = item_field @@ -31,6 +39,24 @@ class ListField(WritableField): ] return data + def validate(self, value): + super(ListField, self).validate(value) + + if not isinstance(value, list): + raise ValidationError(self.error_messages['invalid_type'] % {'value': value}) + + if self.item_field: + errors = {} + for index, item in enumerate(value): + try: + self.item_field.validate(item) + self.item_field.run_validators(item) + except ValidationError as e: + errors[index] = [e] + + if errors: + raise ValidationError(errors) + class DictField(WritableField): """ @@ -38,6 +64,10 @@ class DictField(WritableField): can be another field type (e.g., CharField) or a serializer. """ + default_error_messages = { + 'invalid_type': _('%(value)s is not a dict.'), + } + def __init__(self, value_field=None, unicode_options=None, *args, **kwargs): super(DictField, self).__init__(*args, **kwargs) self.value_field = value_field @@ -58,3 +88,21 @@ class DictField(WritableField): for key, value in data.items() ) return data + + def validate(self, value): + super(DictField, self).validate(value) + + if not isinstance(value, dict): + raise ValidationError(self.error_messages['invalid_type'] % {'value': value}) + + if self.value_field: + errors = {} + for k, v in six.iteritems(value): + try: + self.value_field.validate(v) + self.value_field.run_validators(v) + except ValidationError as e: + errors[k] = [e] + + if errors: + raise ValidationError(errors)