1

I am trying to have a serializer of a Parent model, with a nested serializer as a field, being different regarding another string field.

For example, if the registry_type field is equal to intra I want to use _IntraRegistrySerializer to serialize/deserialize the registry_data field, but if registry_type is equal to slack, I want to use _SlackRegistrySerializer for the same field.

I managed to have the serialization working doing this:

class RegistrySerializer(serializers.ModelSerializer):

    def to_representation(self, instance):
        data = super().to_representation(instance)
        if isinstance(instance, IntraRegistry):
            data["registry_type"] = "intra"
            data["registry_data"] = _IntraRegistrySerializer(instance=instance).data
        if isinstance(instance, SlackRegistry):
            data["registry_type"] = "slack"
            data["registry_data"] = _SlackRegistrySerializer(instance=instance).data
        return data

    class Meta:
        # `Registry` being the parent model of both `IntraRegistry` and `SlackRegistry`
        model = Registry
        fields = ["id", "description"]

But it only does half of what I would like to do.

I tried overloading methods, using SerializerMethodField, and even though I keep on searching and reading the doc I can't manage to find a solution.

1 Answer 1

1

This does seem like a good SerializerMethodField case:

class RegistrySerializer(serializers.ModelSerializer):
    registry_type = serializers.SerializerMethodField()
    registry_data = serializers.SerializerMethodField()

    def get_registry_type(self, obj):
        if isinstance(instance, IntraRegistry):
            return "intra"
        if isinstance(instance, SlackRegistry):
            return "slack"

    def get_registry_data(self, obj):
        if isinstance(instance, IntraRegistry):
            return _IntraRegistrySerializer(instance=obj, context=self.context).data
        if isinstance(instance, SlackRegistry):
            return _SlackRegistrySerializer(instance=obj, context=self.context).data

    class Meta:
        # `Registry` being the parent model of both `IntraRegistry` and `SlackRegistry`
        model = Registry
        fields = ["id", "description", "registry_type", "registry_data"]

The above is the implementation of the serializer method fields and should work since both of the registries inherit from Registry.

You may still need to tweak it to your needs. One difference compared to the current implementation is that the registry_type and registry_data will now always be present. They'll be null if this is a Registry object type or some other child type not handled here.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for this answer, it helped me improve the serialization part! However I am still stuck at the deserialization part... Well I managed to do it, but I lose a lot of the validation features... I don't feel like I am doing it well

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.