Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serializer validate function is not called DRF

class ChildSerializer(serializers.ModelSerializer):


    class Meta:
         model = Child
         fields = '__all__'


class ParentSerializer(serializers.ModelSerializer):
    """
    Serializer for task
    """
    def validate_title(self, data):
        if not data.get('title'):
            raise serializers.ValidationError('Please set title')
        return data

Validate Function is not called when Post ,Also how can i give custom errors to ChildSerializer ,

like image 663
sourabhah Avatar asked Mar 21 '18 07:03

sourabhah


People also ask

How does Django validate serializer data?

To validate any data which data where we need multiple fields together, we can use serializer level, also known as object-level validation. In this type of validation, we can simple override validate the method in the serializer class, and we can either raise serializers.

How do I know if my serializer is valid?

We can validate the serializer by calling the method " is_valid() ". It will return the boolean(True/False) value. If the serializer is not valid then we can get errors by using the attribute "errors".

What is serializer Is_valid?

is_valid perform validation of input data and confirm that this data contain all required fields and all fields have correct types. If validation process succeded is_valid set validated_data dictionary which is used for creation or updating data in DB.

What is difference between serializer and ModelSerializer?

The ModelSerializer class is the same as a regular Serializer class, except that: It will automatically generate a set of fields for you, based on the model. It will automatically generate validators for the serializer, such as unique_together validators. It includes simple default implementations of .


2 Answers

I ran into a similar problem where my custom validation field was not being called. I was writing it to bypass an incorrect DRF validation (more details shown below, but not necessary for the answer).

Looking into the DRF source code I found my problem: DRF always validates your field using its code before validating with your custom code.

''' rest-framework/serializers.py '''

for field in fields:
    validate_method = getattr(self, 'validate_' + field.field_name, None)
    primitive_value = field.get_value(data)
    try:
        # DRF validation always runs first!
        # If DRF validator throws, then custom validation is not called
        validated_value = field.run_validation(primitive_value)
        if validate_method is not None:
            # this is your custom validation
            validated_value = validate_method(validated_value)
    except ValidationError as exc:
        errors[field.field_name] = exc.detail
    except DjangoValidationError as exc:
        errors[field.field_name] = get_error_detail(exc)

Answer: Custom validators cannot be used to bypass DRF's validators, as they will always run first and will raise an exception before you can say it is valid.

(for those interested, the validation error I hit was like this: ModelSerializer used for ModelA, which has a OneToOne relation to ModelB. ModelB has a UUID for its pk. DRF throws the error '53abb068-0286-411e-8729-0174635c5d81' is not a valid UUID. when validating, which is incorrect, and really infuriating.)

like image 104
sean.hudson Avatar answered Oct 16 '22 17:10

sean.hudson


Your ParentSerializer validation method has some issues. Assumes that there is a title field in your ParentSerializer model. For field level validation, you will get the field instead of whole data. That is validate_title function should have title(title field of the data) as parameter not data. So you dont have to check data.get('title') for the existance of title. Reference

class ParentSerializer(serializers.ModelSerializer):
    """
    Serializer for task
    """
    def validate_title(self, title):
        if not title:
            raise serializers.ValidationError('Please set title')
        return title
like image 20
Aneesh R S Avatar answered Oct 16 '22 17:10

Aneesh R S