[Django]-Nested serializer "Through model" in Django Rest Framework

5👍

Based on the way you would like to show your output, I suggest you change your models to:

class Group(models.Model):
    name = models.CharField(max_length=20)
    members = models.ManyToManyField(
        'Membership',
        related_name='groups',
        related_query_name='groups',
    )


class Member(models.Model):
    name = models.CharField(max_length=20)


class Membership(models.Model):
    group = models.ForeignKey(
        'Group',
        related_name='membership',
        related_query_name='memberships',
    )
    join_date = models.DateTimeField()

How Group model and Member model are ManytoMany, does not have a problem you let the relationship in Group model. It will be the easiest to output it in serialize. related_name and related_query_name are used to make the serialization and point the nested relation.

And finally, your serialize could be like this (I exemplified it with a create method):

class MembershipSerializer(ModelSerializer):
    class Meta:
        fields = ("id", "join_date",)


class GroupSerializer(ModelSerializer):
    memberships = MembershipSerializer(many=True)

    class Meta:
        model = Group
        fields = ("id", "name", "memberships",)


class MemberSerializer(ModelSerializer):
    groups = GroupSerializer(many=True)

    class Meta:
        model = Member
        fields = ("id", "name", "groups")

    def create(self):
        groups_data = validated_data.pop('groups')
        member = Member.objects.create(**validated_data)
        for group in groups_data:
            memberships_data = group.pop('memberships')
            Group.objects.create(member=member, **group)
            for memberhip in memberships:
                Membership.objects.create(group=group, **memberships)

The output will be:

{
  "id": 1,
  "name": "Paul McCartney",
  "groups": [
    {
      "id": 3,
      "name": "Beatles",
      "memberships": [
        {
          "id": 2,
          "join_date": "2018-08-08T13:43:45-0300"
        }
      ]
    }
  ]
}

In this output, I am not “nesting” the parent id but you can make it too, just declare into fields attributes.

👤Aipi

0👍

By looking at your output it seems you want to show membership inside groups and groups inside member. I would recommend editing the serializer to something like this.

class MemberSerializer(ModelSerializer):
    groups = GroupSerializer(many=True)         
    class Meta:
        model = Member
        fields = ("id","name","groups")

class GroupSerializer(ModelSerializer):
    membership = MembershipSerializer()        
    class Meta:
        model = Group
        fields = ("id","name","membership")

class MembershipSerializer(ModelSerializer):
    class Meta:
        model = Membership
        fields = "__all__"

Leave a comment