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

前端 未结 4 1389
忘掉有多难
忘掉有多难 2021-02-02 07:08

I have a serializer that validates fields based on the values of other fields, In the error response I would like to show each field error as a field error as opposed to showing

相关标签:
4条回答
  • 2021-02-02 07:31

    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.

    0 讨论(0)
  • 2021-02-02 07:36

    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.

    0 讨论(0)
  • 2021-02-02 07:43

    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
    
    0 讨论(0)
  • 2021-02-02 07:43

    In case you are using built-in validators in DRF (which are in-fact django core validators) you have to preprocess django ValidationError coming from validator with a function get_error_detail drf is using for this purpose.

    def _validate_min_value(self, data, key):
            try:
                MinValueValidator(Decimal('0.01'))(data.get(key))
            except ValidationErrorDjango as exc:
                raise ValidationError(
                    {key: get_error_detail(exc)}
                )
    

    Note that ValidationErrorDjango is a ValidationError from django.core.exceptions, while ValidationError is a one from rest_framework.exceptions

    0 讨论(0)
提交回复
热议问题