django rest framework: set field-level error from serializer validate() method

Similarly to the answer by @Jkk.jonah, this raises a ValidationError, but it reuses the original exception text without need to re-implement translations:

try:
    serializer.fields['field_val1'].fail('required')
except ValidationError as exc:
    raise ValidationError({
        'field_val1': exc.detail,
    })

By default (i.e. on rest_framework.fields.Field class), available keys are:

default_error_messages = {
    'required': _('This field is required.'),
    'null': _('This field may not be null.')
}

Subclasses can add their own error messages there (and Serializer is a subclass of Field).

BTW, new error messages will be automagically merged with existing (inherited) messages - won't be overridden as might be expected.


If you have logic that applies to all the fields, you can still get the desired result by doing this:

def validate(self, data):
    for key, value in data.items():
        # checks if value is empty
        if not value:
            raise serializers.ValidationError({key: "This field should not be left empty."})

    return data

I figured it out, on this page of the documentation in the "BaseSerializer" section, there's an example that shows ValidationError can take a dictionary argument upon initialization.

If I raise ValidationError({'field_val1': ['this field is not valid']}) I get the JSON response I want.