def run_validation(self, data=empty): """ We patch this function because we want to see all the errors at once. """ (is_empty_value, data) = self.validate_empty_values(data) if is_empty_value: return data errors = OrderedDict() try: data = self.to_internal_value(data) except ValidationError as exc: errors.update(exc.detail) try: self.run_validators(data) except (ValidationError, DjangoValidationError) as exc: errors.update(get_validation_error_detail(exc)) try: data = self.validate(data) assert data is not None, '.validate() should return the validated data' except (ValidationError, DjangoValidationError) as exc: errors.update(get_validation_error_detail(exc)) if errors: raise ValidationError(errors) return data
def run_validation(self, data=rest_framework.fields.empty): """Overrides rest_framework.serializers.Serializer.run_validation in order to report errors at both the field level and the serializer level. In the parent class, if field-level errors were raised, then serializer-level errors were not reported """ (is_empty_value, data) = self.validate_empty_values(data) if is_empty_value: return data errors = {} value = data try: value = self.to_internal_value(data) except (ValidationError, DjangoValidationError) as exc: errors.update(get_validation_error_detail(exc)) try: self.run_validators(value) value = self.validate(value) assert value is not None, '.validate() should return the validated data' except (ValidationError, DjangoValidationError) as exc: errors.update(get_validation_error_detail(exc)) if errors: raise ValidationError(detail=errors) return value
def test_nested_validation_error_detail(self): """ Ensure nested validation error detail is rendered correctly. """ e = serializers.ValidationError({'nested': { 'field': ['error'], }}) self.assertEqual(serializers.get_validation_error_detail(e), {'nested': { 'field': ['error'], }})
def run_validation(self, data=serializers.empty): # data is a dictionary errs = defaultdict(list) email = data.get('email', False) if email and get_user_model().objects.filter(email__iexact=email).exists(): errs['email'].append(_("A user with that email already exists.")) try: validated_data = super().run_validation(data) except (exceptions.ValidationError, DjangoValidationError) as exc: errs.update(serializers.get_validation_error_detail(exc)) if errs: raise exceptions.ValidationError(errs) return validated_data
def validate(self, attrs): if attrs.get("plugin_data"): section = Section.objects.get(pk=self.context["comment_parent"]) try: if not section.plugin_identifier: raise ValidationError("The section %s has no plugin; no plugin data is allowed." % section) plugin = section.plugin_implementation attrs["plugin_data"] = plugin.clean_client_data(attrs["plugin_data"]) except (ValidationError, DjangoValidationError) as ve: # Massage the validation error slightly... detail = get_validation_error_detail(ve) detail.setdefault("plugin_data", []).extend(detail.pop(api_settings.NON_FIELD_ERRORS_KEY, ())) raise ValidationError(detail=detail) attrs["plugin_identifier"] = section.plugin_identifier return attrs
def test_nested_validation_error_detail(self): """ Ensure nested validation error detail is rendered correctly. """ e = serializers.ValidationError({ 'nested': { 'field': ['error'], } }) self.assertEqual(serializers.get_validation_error_detail(e), { 'nested': { 'field': ['error'], } })
def run_validation(self, data=serializers.empty): # data is a dictionary errs = defaultdict(list) for field in self.Meta.required_translated_fields: if not any( data.get(key, False) for key in generate_translated_fields(field, False)): errs[field].append(_('This field is required.')) try: validated_data = super().run_validation(data) except (exceptions.ValidationError, DjangoValidationError) as exc: errs.update(serializers.get_validation_error_detail(exc)) if errs: raise exceptions.ValidationError(errs) return validated_data
def run_validation(self, data=serializers.empty): # data is a dictionary errs = defaultdict(list) for field in self.Meta.required_translated_fields: if not (data.get('%s_en' % field, False) or data.get('%s_ar' % field, False) or data.get('%s_fr' % field, False)): errs[field].append(_('This field is required.')) try: validated_data = super().run_validation(data) except (exceptions.ValidationError, DjangoValidationError) as exc: errs.update(serializers.get_validation_error_detail(exc)) if errs: raise exceptions.ValidationError(errs) return validated_data
def update(self, instance, validated_data): user_data = validated_data.pop('user', None) if user_data is not None: for attr, value in user_data.items(): setattr(instance.user, attr, value) try: instance.user.full_clean() if 'email' in user_data: if User.objects.filter(email=instance.email).exclude(pk=instance.pk).count(): raise serializers.ValidationError("Field `Email` must be unique.") except DjangoValidationError as exc: raise serializers.ValidationError(detail=serializers.get_validation_error_detail(exc)) instance.user.save() for attr, value in validated_data.items(): setattr(instance, attr, value) instance.save() return instance
def validate(self, attrs): if attrs.get("plugin_data"): section = attrs["section"] try: if not section.plugin_identifier: raise ValidationError("The section %s has no plugin; no plugin data is allowed." % section) plugin = section.plugin_implementation attrs["plugin_data"] = plugin.clean_client_data(attrs["plugin_data"]) except (ValidationError, DjangoValidationError) as ve: # Massage the validation error slightly... detail = get_validation_error_detail(ve) detail.setdefault("plugin_data", []).extend(detail.pop(api_settings.NON_FIELD_ERRORS_KEY, ())) raise ValidationError(detail=detail) attrs["plugin_identifier"] = section.plugin_identifier if not (attrs.get("plugin_data") or attrs.get("content") or attrs.get("label")): raise ValidationError("Either content, plugin data or label must be supplied.") return attrs
def validate(self, attrs): if attrs.get("plugin_data"): section = Section.objects.get(pk=self.context["comment_parent"]) try: if not section.plugin_identifier: raise ValidationError( "The section %s has no plugin; no plugin data is allowed." % section) plugin = section.plugin_implementation attrs["plugin_data"] = plugin.clean_client_data( attrs["plugin_data"]) except (ValidationError, DjangoValidationError) as ve: # Massage the validation error slightly... detail = get_validation_error_detail(ve) detail.setdefault("plugin_data", []).extend( detail.pop(api_settings.NON_FIELD_ERRORS_KEY, ())) raise ValidationError(detail=detail) attrs["plugin_identifier"] = section.plugin_identifier return attrs
def run_partial_validation(self, data=fields.empty): """ We override the default `run_validation`, because the validation performed by validators and the `.validate()` method should be coerced into an error dictionary with a 'non_fields_error' key. """ # Called 1 time for all the data list # output of this function is set into self._validated_data by is_valid (is_empty_value, data) = self.validate_empty_values(data) if is_empty_value: return data value, detail = self.to_internal_value_error(data) try: self.run_validators(value) # does nothing in our case value = self.validate(value) assert value is not None, \ '.validate() should return the validated data' except (ValidationError, DjangoValidationError) as exc: raise ValidationError(detail=get_validation_error_detail(exc)) return value, detail
def validate(self, attrs): if attrs.get("plugin_data"): section = attrs["section"] try: if not section.plugin_identifier: raise ValidationError( "The section %s has no plugin; no plugin data is allowed." % section) plugin = section.plugin_implementation attrs["plugin_data"] = plugin.clean_client_data( attrs["plugin_data"]) except (ValidationError, DjangoValidationError) as ve: # Massage the validation error slightly... detail = get_validation_error_detail(ve) detail.setdefault("plugin_data", []).extend( detail.pop(api_settings.NON_FIELD_ERRORS_KEY, ())) raise ValidationError(detail=detail) attrs["plugin_identifier"] = section.plugin_identifier if not (attrs.get("plugin_data") or attrs.get("content") or attrs.get("label")): raise ValidationError( "Either content, plugin data or label must be supplied.") return attrs
def run_validation(self, data=[]): """ We override the default `run_validation`, because the validation performed by validators and the `.validate()` method should be coerced into an error dictionary with a 'non_fields_error' key. """ (is_empty_value, data) = self.validate_empty_values(data) if is_empty_value: return data try: value = self.to_internal_value(data) self.run_validators(value) value = self.validate(value) assert value is not None, '.validate() should return the validated data' # noqa except (ValidationError, DjangoValidationError) as exc: # TODO: Must be 'recipient' instead of 'to' in v2 raise ValidationError(detail={ 'to': data['to'], 'errors': get_validation_error_detail(exc) }) return value