How to serialize when fields are not known in django-rest-framework?

I want to serialize a dictionary where field_name is not fixed, it can be anything and i need to validate if type of field_value is correct according to what type should be provided to field_name. e.g:

{
   "attributes": {
         attribute_name: attribute_vale
         .
         .
         .
         (can contain such more pairs)
   }
}

Is there any serializer way that can help me to serialize the key-value pair of attributes dictionary?

You can dynamically get the model's fields with:

 mymodel._meta.get_fields()

So you can create dynamic serializers with:

    def get_serializer(self, include_fields: list[str]=None, readonly_fields: list[str]=None):
        class AnySerializer(ModelSerializer):
            class Meta:
                model = self.__class__
                fields = [field.name for field in self._meta.get_fields()] if not include_fields else include_fields
                read_only_fields = ['pk'] if not readonly_fields else readonly_fields
        return AnySerializer(self, many=False)

as a method on your model. Then you can call:

mymodel = MyModel.objects.all().first() # Get an instance
serializer = mymodel.get_serializer() # Dynamically create a serializer
serialized_data = serializer.data # Serialized JSON data

You can validate types entered into the field with:

# I'm sure there's a way of dynamically validating the fields before saving. 
# I just don't have that answer.
for field in self._meta.get_fields():
    if field.get_internal_type() is models.EmailField:
        field_data = getattr(self, field.name)
        validate data...
    elif ...

With this method, you can define readonly fields, and include_fields. If none are provided, all fields will be serialized. I'm pretty sure Django model validation still applies to serializers, so you could set up your validation there.

This is a method for a model, but I myself use it on querysets. (use self.model in querysets to access the model from the queryset.)

Back to Top