Manytomany Relation Custom Serializer
Assume I have two models: class IPAddress(models.Model): address = models.CharField() class Rule(models.Model): name = models.CharField() ips = models.ManyToMany(IPAdd
Solution 1:
If you need to return an instance of Rule
in following format:
{"name":"Foo","ips":["192.168.1.40","4.4.4.4","8.8.8.8"]}
You could create a RuleSerializer
and use SlugRelatedField
.
SlugRelatedField
only works with the objects which already exist. Since you would be creating objects as well, you could modify the to_internal_value
implementation to create the objects which doesn't exist (referenced from here):
classCreatableSlugRelatedField(serializers.SlugRelatedField):
defto_internal_value(self, data):
try:
return self.get_queryset().get_or_create(**{self.slug_field: data})[0]
except ObjectDoesNotExist:
self.fail('does_not_exist', slug_name=self.slug_field, value=smart_text(data))
except (TypeError, ValueError):
self.fail('invalid')
classRuleSerializer(serializers.ModelSerializer):
ips = serializers.CreatableSlugRelatedField(
many=True,
slug_field='address'# this is the ip address
queryset=IPAddress.objects.all()
)
classMeta:
model = Rule
fields: ('name', 'ips')
UPDATE: Based on the comments in the question:
I could not change the request I get and the response I must send
But if you could then use nested serializers though your representation would need to change slightly:
{
"name": "Foo",
"ips": [
{"address": "192.168.1.40"},
{"address": "4.4.4.4"},
{"address": "8.8.8.8"}
]
}
and, then the nested serializers (more documentation here):
classIPAddressSerializer(serializers.ModelSerializer):
classMeta:
model = IPAddress
fields: ('address',)
classRuleSerializer(serializers.ModelSerializer):
ips = IPAddressSerializer(many=True)
classMeta:
model = Rule
fields: ('name', 'ips')
Post a Comment for "Manytomany Relation Custom Serializer"