Skip to main content
 首页 » 编程设计

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

2025年05月04日22linjiqin

我正在尝试使用请求中的以下内容将消息发布到数据库:

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

相反,我收到错误消息“无法分配“OrderedDict([(u'name', doc'), (u'email', u'')])”:“Message.author”必须是“作者“实例”

每条消息都有一个相关的作者记录,数据库中可能已经存在也可能不存在。在这一点上,我不介意在该表上重复输入。

我的 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') 

我完全不知道应该如何进行,我是否期望 AuthorSerializer 能够将列表或有序字典解析为新的或现有的对象。

请您参考如下方法:

根据docs ,您必须在自定义创建方法中创建嵌套对象:

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)