DRF 3 - Creating Many-to-Many update/create serializer with though table

后端 未结 2 459
我寻月下人不归
我寻月下人不归 2021-01-31 18:37

I am trying to create a reference app in DRF 3 to demonstrate a nested serializer that can create/update models. The sample code below bombs with \"*create() argument after **

2条回答
  •  佛祖请我去吃肉
    2021-01-31 19:10

    I have no clue if there is an easier way, but the only way I managed to get this to work is to reference the 'through' model "memberships" in the Group serializer and write custom code for .create() and .update(). This seems like a lot of work to just set M2M FK's. If someone knows a better way I'd love to hear it.

    class GroupMembershipSerializer(ModelSerializer):
        class Meta:
            model = Membership
            fields = ('person',)
    
    class GroupCreateSerializer(ModelSerializer):
         memberships = GroupMembershipSerializer(many=True, required=False)
    
        def create(self, validated_data):
            person_data = validated_data.pop('memberships')
            group = Group.objects.create(**validated_data)
            for person in person_data:
                d=dict(person)
                Membership.objects.create(group=group, person=d['person'])
            return group
    
        def update(self, instance, validated_data):
            person_data = validated_data.pop('memberships')
            for item in validated_data:
                if Group._meta.get_field(item):
                    setattr(instance, item, validated_data[item])
            Membership.objects.filter(group=instance).delete()
            for person in person_data:
                d=dict(person)
                Membership.objects.create(group=instance, person=d['person'])
            instance.save()
            return instance
    
        class Meta:
            model = Group
    
    class GroupCreateModelViewSet(ModelViewSet):
        serializer_class = GroupCreateSerializer
        queryset = Group.objects.all()
    

    So you can create a new Group with related Person(s) using:

     { 
         "name" : "Group 1", 
         "memberships" : [ 
             { "person" : 1 },
             { "person" : 2 }
         ]
     }
    

提交回复
热议问题