I'm novice in python and django rest. But I'm confused. What is the best way to update many to many relation in django rest framework. I read the docs http://www.django-rest-framework.org/api-guide/relations/#manytomanyfields-with-a-through-model By default, relational fields that target a ManyToManyField with a through model specified are set to read-only.
If you explicitly specify a relational field pointing to a ManyToManyField with a through model, be sure to set read_only to True.
So if I have a code
class Master(models.Model): # other fields skills = models.ManyToManyField(Skill) class MasterSerializer(serializers.ModelSerializer): skills = SkillSerializer(many=True, read_only=False)
This will return skills as list of objects. And I don't have a way to update them. As far as I understood Django prefers work with objects vs object id when it comes to M2M. If I work with yii or rails I will work with "through" models. I would like to get skill_ids field. That I could read and write. And I can do this for write operation
class MasterSerializer(serializers.ModelSerializer): skill_ids = serializers.ListField(write_only=True) def update(self, instance, validated_data): # ... validated_data['skill_ids'] = filter(None, validated_data['skill_ids']) for skill_id in validated_data['skill_ids']: skill = Skill.objects.get(pk=skill_id) instance.skills.add(skill) return instance
But I cannot make it return skill_ids in field. And work for read and write operations.
A few things to note.
First, you don't an explicit through table in your example. Therefore you can skip that part.
Second is you are trying to use nested serializers which are far more complex than what you're trying to achieve.
You can simply read/write related id by using a PrimaryKeyRelatedField:
class MasterSerializer(serializers.ModelSerializer): skills_ids = serializers.PrimaryKeyRelatedField(many=True, read_only=False, queryset=Skill.objects.all(), source='skills')
Which should be able to read/write:
{id: 123, first_name: "John", "skill_ids": [1, 2, 3]}
Note that the mapping from JSON's "skill_ids" to model's "skills" is done by using the optional argument source
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With