Reputation: 113
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.
Upvotes: 1
Views: 974
Reputation: 1730
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.
Upvotes: 1