【问题标题】:Nested serializer using foreign key with only one object in DRF使用外键的嵌套序列化程序,DRF 中只有一个对象
【发布时间】:2018-07-24 13:17:32
【问题描述】:

我正在使用具有两个模型的 Django Rest Framework,一个服务和一个消息,其中一个服务可以有许多消息。使用外键。

class Service(models.Model):
    servicename = models.TextField(blank=False)
    sender = models.TextField(blank=False)


class Message(models.Model):

    service = models.ForeignKey(Service, related_name='messages', on_delete=models.CASCADE)
    description = models.TextField(blank=False)

唯一的用例是您输入服务的地方,该服务嵌套以获取消息的输入。因此,服务将同时创建服务和消息。如果服务不存在,则会创建它。如果确实存在,则消息将指向服务。

由于它是一对多的,我的序列化程序中似乎需要many=True,这是不可取的,因为从来没有同时输入两条消息的用例,也意味着 Web UI 将无法工作因为不支持列表。

class MessageSerializer(serializers.ModelSerializer):

    class Meta:
        model = Message
        fields = ('description',)


class ServiceSerializer(serializers.ModelSerializer):

    messages = MessageSerializer(many=True)

    class Meta:
        model = Service
        fields = ('servicename', 'sender', 'messages')

    def create(self, validated_data):
        messages_data = validated_data.pop('messages')
        print(messages_data)
        service, created = Service.objects.get_or_create(
            servicename=validated_data['servicename'],
            sender=validated_data['sender']
        )
        Message.objects.create(service=service, **messages_data[0])
        return service

那么,在输入期间是否可以有一个只有一个对象的嵌套序列化程序?删除 many=True 会导致典型的 AttributeError ,我已经理解这意味着它是不允许的,因为一对多的反向意味着它需要具有获取多个对象的能力。

谢谢

【问题讨论】:

标签: django django-rest-framework


【解决方案1】:

我建议您为此使用两个不同的字段。

类似这样的:

class ServiceSerializer(serializers.ModelSerializer):

    messages = MessageSerializer(many=True, read_only=True)
    message = MessageSerializer(write_only=True)

因此,对于输入-您将只有 write_only 属性,该属性在输出时不会被序列化-仅在您发布时(您可以决定使用required 属性使其成为可选)

消息反之亦然 - 只读。

然后你在 create 方法中相应地处理它。

【讨论】:

  • 谢谢,成功了!严格来说,如果我所做的只是 POST 和 GET,我真的需要对 read_only 做任何事情吗?就像现在一样,仅使用 write_only 时,API 中的一切都显示得很好。
  • 不,不是。只是为了确保这是只读属性。
猜你喜欢
  • 1970-01-01
  • 2015-07-09
  • 2020-12-20
  • 2020-05-04
  • 1970-01-01
  • 1970-01-01
  • 2020-10-03
相关资源
最近更新 更多