Django多对一关系将数据添加到多方

时间:2021-03-07 08:03:09

标签: python-3.x django django-models django-rest-framework django-views

我有两个像下面这样的模型。我正在使用 Django restframework。

class Family(models.Model):
    name= models.CharField(max_length=100)

class Parishioner(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    family = models.ForeignKey(Family, on_delete=models.CASCADE)

有我的视图集

class FamilyViewSet(viewsets.ModelViewSet):
    queryset = Family.objects.all()
    serializer_class = FamilySerializer
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

class ParishionerViewSet(viewsets.ModelViewSet):
    queryset = Parishioner.objects.all()
    serializer_class = serializers.ParishionerSerializer
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

这些是我的序列化程序

class FamilySerializer(serializers.ModelSerializer):

    class Meta:
        model = Family
        fields = ('id', 'name')
        read_only_fields = ('id',)


class ParishionerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Parishioner
        fields = ('id', 'first_name', 'last_name', 'family')
        read_only_fields = ('id',)
        depth = 1

所以基本上 Parishioner 可以有一个 FamilyFamily 有多个 members(Parishioners)

目前我必须转到所有 Parishioners 并选择 Family

是否可以将名为 members 的字段添加到 Family 模型,其中成员将是 ArrayExisting Parishioners ? 或者有没有其他方法可以解决这个问题?

enter image description here

2 个答案:

答案 0 :(得分:2)

在数据库端这样做是个坏主意,因为这意味着数据库不再检查这个。

但是您可以在序列化程序中轻松完成此操作。为此,我们将 ParishionerSerializer 的实例添加到 FamilySerializer。我们需要在 ParishionerSerializer 之前定义 FamilySerializer ,否则,该标识符尚未分配:

class ParishionerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Parishioner
        fields = ('id', 'first_name', 'last_name', 'family')
        read_only_fields = ('id',)
        depth = 1


class FamilySerializer(serializers.ModelSerializer):
    parishioner_set = ParishionerSerializer(many=True, read_only=True)

    class Meta:
        model = Family
        fields = ('id', 'name')
        read_only_fields = ('id',)

您可以在模型层将其重命名为 members,然后相应地更新序列化程序,或仅在子序列化程序中更新。

选项 1:使用 related_name=…

我们可以通过为 related_name=… [Django-doc] 指定一个值来将关系重命名为 memebers

class Parishioner(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    family = models.ForeignKey(
        Family,
        on_delete=models.CASCADE,
        related_name='members'
    )

然后序列化器因此使用 member 代替:

class FamilySerializer(serializers.ModelSerializer):
    members = ParishionerSerializer(many=True, read_only=True)

    class Meta:
        model = Family
        fields = ('id', 'name')
        read_only_fields = ('id',)

选项 2:使用 source=… 重命名序列化程序

我们也可以只在序列化器级别指定它,通过指定一个 source=… parameter [drf-doc]:

class FamilySerializer(serializers.ModelSerializer):
    members = ParishionerSerializer(
        source='parishioner_set',
        many=True,
        read_only=True
    )

    class Meta:
        model = Family
        fields = ('id', 'name')
        read_only_fields = ('id',)

答案 1 :(得分:0)

Fam = Family.objects.get(id=1) Fam.parishioner_set.all()

应该这样做

相关问题