[Fixed]-Django REST Framework serializer validation

1👍

DRF allows for field level validation. Have your function name as: def validate_(fieldname). and drf will run that function against the corresponding field name. In the code below, “validate_item_date”, drf corresponds that to the field “item_date”.

class OrderItemSerializer(serializers.ModelSerializer):
    item_date = serializers.DateTimeField()

    class Meta:
        model = Item

    def validate_item_date(self, value):
        if value < 10:
            raise ValidationError('')
        return value

0👍

You can add validation to serializer like this

class OrderItemSerializer(serializers.ModelSerializer):
    def validate_item_date(self, item_date):
        if item_date < {something}:
            raise ValidationError('')
        return item_date
👤Anna

0👍

In your example item_date parameter in the validator function will be the validated data of the whole OrderItemSerializer (serializer.validated_data).

Here is how it should be:

def validate_item_date(validated_data):
    if validated_data.get('item_date') < {something}:
        raise ValidationError('')

By using serializer-lever validation you can validated against other fields of the serializer:

def validate_item_date(validated_data):
    if validated_data.get('item_date') < validated_data.get('order_attr'):
        raise ValidationError('')

Of course you should handle None values and dates comparison properly here, this is simplified version of the code.

You can use class-based validator if you want to specify {something} statically.

class OrderItemValidator:
    def __init__(self, a):
        self.a = a

    def __call__(self, value, *args, **kwargs):
        item_date = value.get('item_date')
        if item_date < self.a:
            raise serializers.ValidationError('')

class OrderItemSerializer(serializers.ModelSerializer):
    ...

    class Meta:
        validators = [OrderItemValidator(some_date)]

Be careful to not using something like that OrderItemValidator(timezone.now()) here :).

You can also specify field level validator

item_date = serializers.DateTimeField(validators=[OrderItemValidator(some_date)])

In this case this field’s validated data will be passed to the validator function instead of the whole serializer’s validated data.

Leave a comment