Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework serializers.DictField constraint on possible keys

I have a REST API output that looks like this:

{
  "something": "xyz"
  "something_dict" {
    "a": 10,
    "b": 20,
    "c": 30
  }
}

I'm trying to create a serializer for that (mostly for automatic documentation generation purposes, but I believe that doesn't really matter), and for the something_dict field I thought it could be a good idea to use serializers.DictField.

The problem is, the keys that can show up in the dictionary are limited to a certain set (values of an enum type), but I can't seem to find a good way to define it.

Something like serializers.DictField(key=serializers.ChoiceField(choices=[enum.value for enum in Enum])) would be great but that's obviously not available.

The only reasonable way to specify this is to use a nested serializer:

class SomethingDict(serializers.Serializer):
   a = serializers.IntField(required=False)
   b = serializers.IntField(required=False)
   c = serializers.IntField(required=False)

But that's slightly inconvenient as the set of available keys is potentially dynamic (values of an enum, as mentioned previously).

The question is then:

Is it possible to specify possible values for serializer.DictField keys or is there any way around it to make it dynamic? (I'd like to avoid defining the class in dynamic way, if possible)

like image 589
Matek Avatar asked Oct 25 '25 08:10

Matek


1 Answers

Django Rest Framework provides a DictField serializer field that can be used to handle dictionaries in your API.

You can add a constraint on the possible keys of the dictionary by subclassing DictField and overriding the to_internal_value() method to perform the necessary validation.

Have a look at this example,

from rest_framework import serializers

class ConstrainedDictField(serializers.DictField):
    def to_internal_value(self, data):
        # Perform validation on the keys of the dictionary here
        if set(data.keys()) != {"key1", "key2"}:
            raise serializers.ValidationError("Invalid keys for dictionary.")
        return super().to_internal_value(data)

You can then use the ConstrainedDictField in your serializer like this:

class MySerializer(serializers.Serializer):
    my_dict = ConstrainedDictField()

It will only accept dictionary with key key1 and key2.

like image 73
Arjun Avatar answered Oct 26 '25 23:10

Arjun