Django Rest Framework 中的嵌套序列化器“通过模型”

bde*_*dex 3 python django django-rest-framework

我在序列化中间“枢轴”模型并附加到 Django Rest Framework 中多对多关系中的每个项目时遇到困难。

例子:

模型.py:

class Member(models.Model):
    name = models.CharField(max_length = 20)
    groups = models.ManyToManyField('Group', through='Membership')

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

class Membership(models.Model):
    member = models.ForeignKey('Member')
    group = models.ForeignKey('Group')
    join_date = models.DateTimeField()
Run Code Online (Sandbox Code Playgroud)

序列化器.py:

class MemberSerializer(ModelSerializer):
    class Meta:
        model = Member

class GroupSerializer(ModelSerializer):
    class Meta:
        model = Group

class MembershipSerializer(ModelSerializer):
    class Meta:
        model = Membership
Run Code Online (Sandbox Code Playgroud)

我尝试遵循答案: Inclusion intermediary (through model) in returns in Django Rest Framework

但这不完全是我需要的

我需要生成以下输出

{
  "id": 1,
  "name": "Paul McCartney",
  "groups": [
    {
      "id": 3,
      "name": "Beatles",
      "membership": {
        "id": 2,
        "member_id": 1,
        "group_id": 3,
        "join_date": "2018-08-08T13:43:45-0300"
      }
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

在此输出中,我返回组中每个项目的相关“通过模型”。

如何以这种方式生成序列化模型?

Aip*_*ipi 5

根据您想要显示输出的方式,我建议您将模型更改为:

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()
Run Code Online (Sandbox Code Playgroud)

Group模型和Member模型如何ManytoMany,没有问题你让Group模型中的关系。在序列化中输出它是最简单的。related_namerelated_query_name用于进行序列化和指向嵌套关系。

最后,您的序列化可能是这样的(我用 create 方法举例说明):

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)
Run Code Online (Sandbox Code Playgroud)

输出将是:

{
  "id": 1,
  "name": "Paul McCartney",
  "groups": [
    {
      "id": 3,
      "name": "Beatles",
      "memberships": [
        {
          "id": 2,
          "join_date": "2018-08-08T13:43:45-0300"
        }
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

在此输出中,我没有“嵌套”父 ID,但您也可以这样做,只需在 fields 属性中声明即可。