简体   繁体   English

在Django Rest Framework中保存相关的嵌套对象

[英]saving related nested object in Django Rest Framework

I am trying to post a message to the database using the following content on the request: 我正在尝试使用请求中的以下内容将消息发布到数据库:

{
    "thread": 1,
    "content": "lorem ipsum",
    "author": 
    {
        "name":"doc",
        "email":""
    }

}

Instead I get the error message of "Cannot assign "OrderedDict([(u'name', doc'), (u'email', u'')])": "Message.author" must be a "Author" instance." 相反,我收到“无法分配” OrderedDict([(u'name',doc'),(u'email',u'')]))错误消息:“ Message.author”必须是“ Author”实例”。

Each Message has a related author record, that may or may not exist already in the database. 每个消息都有一个相关的作者记录,该记录可能已经存在或可能不存在于数据库中。 At this point I don't mind having repeat entries on that table. 在这一点上,我不介意在该表上重复输入。

My serializers.py file has the following: 我的serializers.py文件具有以下内容:

class AuthorSerializer(serializers.Serializer):
    pk = serializers.IntegerField(read_only=False, required=False)
    name = serializers.CharField(required=True, max_length=50)
    email = serializers.CharField(allow_blank=True, allow_null=True, required=False)

    def create(self, validated_data):
        """
        Create and return a new `Author` instance, given the validated data.
        """
        return Author.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """
        Update and return an existing `Author` instance, given the validated data.
        """
        instance.name = validated_data.get('name', instance.name)
        instance.email = validated_data.get('email', instance.email)
        instance.save()
        return instance

class Meta:
    model = Author
    fields = ('name', 'email')

class MessageSerializer(serializers.Serializer):
    pk = serializers.IntegerField(read_only=True)
    thread = serializers.PrimaryKeyRelatedField(queryset=Thread.objects.all())
    created_at = serializers.DateTimeField(required=False)
    content = serializers.CharField(style={'base_template': 'textarea.html'})
    author = AuthorSerializer(required=False, read_only=False)

    def create(self, validated_data):
        """
        Create and return a new `Message` instance, given the validated data.
        """
        return Message.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """
        Update and return an existing `Message` instance, given the validated data.
        """
        instance.thread = validated_data.get('thread', instance.thread)
        instance.content = validated_data.get('content', instance.content)
        instance.author = validated_data.get('author', instance.author)
        instance.save()
        return instance

    class Meta:
        model = Message
        fields = ('thread', 'created_at', 'content', 'author')

I'm quite lost on how I should proceed, has I expected that AuthorSerializer would be able to parse a list or ordered dictionary into a new or existing object. 如果我期望AuthorSerializer能够将列表或有序字典解析为新对象或现有对象,我就该继续进行了很多工作。

According to the docs , you have to create the nested object in your custom create method: 根据docs ,您必须使用自定义的create方法创建嵌套对象:

class MessageSerializer(serializers.Serializer):
    pk = serializers.IntegerField(read_only=True)
    thread = serializers.PrimaryKeyRelatedField(queryset=Thread.objects.all())
    created_at = serializers.DateTimeField(required=False)
    content = serializers.CharField(style={'base_template': 'textarea.html'})
    author = AuthorSerializer(required=False, read_only=False)

    def create(self, validated_data):
        """
        Create and return a new `Message` instance, given the validated data.
        """
        author_data = validated_data.pop('author', None)
        if author_data:
            author = Author.objects.get_or_create(**author_data)[0]
            validated_data['author'] = author
        return Message.objects.create(**validated_data)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM