【问题标题】:Django Many-To-One Relationship add data to Many sideDjango 多对一关系将数据添加到多方
【发布时间】:2021-06-05 10:08:35
【问题描述】:

我有两个模型,如下所示。我正在使用 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 ? 还是有其他方法可以解决这个问题?

【问题讨论】:

  • 在数据库端这样做是个坏主意,因为这意味着数据库不再检查这个。但是您可以在序列化程序中轻松做到这一点。

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


【解决方案1】:

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

应该这样做

【讨论】:

  • 我应该在哪里添加它?
  • 只要您想访问特定家庭的成员。在您的代码中执行此操作。
【解决方案2】:

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

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

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',)

【讨论】:

  • 我尝试了你的建议。它只是在“Family” GET 请求中列出所有“Parishioner”详细信息。但我无法在“家庭”Django api 屏幕中添加“教区居民”。不在 POST 或 PUT 中。我在描述中添加了截图
  • @AMendis: 那么你应该删除read_only=True
  • 我收到“HTML 输入当前不支持列表”。在 Django 屏幕中
  • @AMendis:但这只是 前端 的问题,而不是 REST API 本身的问题。
  • 好的,现在问题是如何发送请求。我尝试发送以下请求 { "name":"Mendis Family", "address":"No 30, Katukurunda", "members":[2] } 但上面的请求给了我以下错误 { "members": [ { "non_field_errors ": [ "无效数据。需要字典,但得到了 int。" ] } ] } 如何将 json 数据发送到 members 字段?还不够吗?
猜你喜欢
  • 2020-03-11
  • 2018-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多