Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django REST - Run field validation from within custom to_internal_value for serializer

I am trying to serialize a JSON like this:

{
    "Some URL": "https://helloworld.com/",
    "Some Integer": 12
    "Some Dictionary": {
        "Nested Array": [...]
        "Nested Dictionary": {...}
    }
}

Writing a serializer with fields with spaces is not allowed (of course because of Python variables), so I'm attempting to subclass BaseSerializer.

class MyNestedSerializer(serializers.BaseSerializer):

    def to_internal_value(self, data):
        nested_array = data.get('Nested Array')
        nested_dictionary = data.get('Nested Dictionary')

        # Validation
        ....
        ....

        return {
            'Nested Array': nested_array,
            'Nested Dictionary': nested_dictionary
        }

    def to_representation(self, instance):
        return {
            'Nested Array': instance['Nested Array'],
            'Nested Dictionary': instance['Nested Dictionary']
        }


class MySerializer(serializers.BaseSerializer):

    def to_internal_value(self, data):
        some_url = data.get('Some URL')
        some_integer = data.get('Some Integer')
        some_dictionary = data.get('Some Dictionary')

        # Validation
        ....
        nested_serializer = MyNestedSerializer(data=some_dictionary)
        nested_serializer.is_valid(raise_exception=True)
        ....

        return {
            'Some URL': some_url,
            'Some Integer': some_integer,
            'Some Dictionary': some_dictionary
        }

    def to_representation(self, instance):
        return {
            'Some URL': instance['Some URL']
            'Some Integer': instance['Some Integer']
            'Some Dictionary': instance['Some Dictionary']
        }

Now normally, I would define the field type in a serializer (not BaseSerializer) like this:

class BasicSerializer(serializers.Serializer):
    some_integer = serializers.IntegerField(min_value=0)
    some_dictionary = serializers.DictField(child=serializers.CharField())

and field validation would occur. What I want is to have these validators run inside my implementation of to_internal_value, instead of writing my own validation. It doesn't make sense to rewrite what has already been written, but I cannot seem to figure out how to run basic validation in my BaseSerializer.

like image 729
gdeamont Avatar asked Dec 14 '25 07:12

gdeamont


1 Answers

The Serializer class is a subclass of BaseSerializer. So in this scenario, there really isn't a need for you to derive from BaseSerializer you can use Serializer instead.

class MySerializer(serializers.Serializer):


    def to_internal_value(self, data):
        some_url = data.get('Some URL')
        some_integer = data.get('Some Integer')
        some_dictionary = data.get('Some Dictionary')

        # Validation
        ....
        nested_serializer = MyNestedSerializer(data=some_dictionary)
        nested_serializer.is_valid(raise_exception=True)
        ....

        return {
            'Some URL': some_url,
            'Some Integer': some_integer,
            'Some Dictionary': some_dictionary
        }

    def to_representation(self, instance):
        return {
            'Some URL': instance['Some URL']
            'Some Integer': instance['Some Integer']
            'Some Dictionary': instance['Some Dictionary']
        }
like image 195
e4c5 Avatar answered Dec 15 '25 21:12

e4c5



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!