Validate specific field in DRF serializer

18.7k views Asked by At

I have a model with a JSONField.

model.py

class Categories(models.Model):
     type = models.CharField(max_length=20)
     name = models.CharField(max_length=500)
     details = JSONField(blank=True, null=True)

Currently I'm using serializers.ModelSerializer for serializing this above model:

serializers.py

class CategoriesSerializer(serializers.ModelSerializer):
     class Meta:
         model = Categories
         fields = ('id', 'type', 'name', 'details')

Due to this, the details field is only checked to contain valid json. What i really need to do is to perform some custom validation based on the Json Schema defined for details field. However since I don't want any other custom validations for rest of the fields, I would like to keep using the validations provided by serializers.ModelSerializer. Is there any way I can override a validation for just one field, probably by writing a custom serializer for just the details field?

Note question is not about how to write a custom Validator, but about how to use that custom validator on a field in the serializer inheriting ModelSerializer

2

There are 2 answers

9
neverwalkaloner On

DRF's serializers provide field level validation option. You can perform details field validation by implementing validate_details method:

class CategoriesSerializer(serializers.ModelSerializer):
     class Meta:
         model = Categories
         fields = ('id', 'type', 'name', 'details')

     def validate_details(self, value):
        if value['not_valid']:
            raise serializers.ValidationError("Not valid")
        return value
0
copser On

The other way around is to validate JSONFiled on Django models level, you can use jsonschema package.

For example

SCHEMA = { put JSON Schema draft here }

Let's validate

from jsonschema import validate, ValidationError

def validate_json_filed(value):
    try:
        validate(value, SCHEMA)
    except ValidationError as e:
        raise serializers.ValidationError(e)

Then just

name = JSONField(validators=[validate_json_field], default=dict, blank=True)

You can validate rest of the field using DRF validators.