You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django DRF基于GenericRelation的可写嵌套序列化器实现问题

错误根因

你的报错发生在序列化器参数校验阶段,还没有执行到你写的create方法:
LastNameSerializer设置了fields = '__all__',会把content_type、object_id两个数据库必填字段默认标记为「请求必填参数」,但你的POST请求没有传递这两个字段,直接触发校验失败。


解决方案

1. 调整LastNameSerializer,标记关联字段为只读

content_type和object_id不需要前端传递,由服务端创建数据时自动赋值,在校验阶段屏蔽必填校验:

class LastNameSerializer(serializers.ModelSerializer):
    class Meta:
        model = LastName
        fields = '__all__'
        # 新增以下配置,标记关联字段为只读
        read_only_fields = ['content_type', 'object_id']

2. 精简PersonSerializer的create方法(可选优化)

创建LastName实例时已经传入content_object=person,Django会自动填充content_type和object_id,不需要再手动调用add关联:

class PersonSerializer(serializers.ModelSerializer):
    last_name = LastNameSerializer(required=False, many=True)
    class Meta:
        model = Person
        fields = ['id','first_name', 'last_name']
    
    def create(self, validated_data):
        # 加默认值兼容不传last_name的场景
        last_names = validated_data.pop('last_name', [])
        person = Person.objects.create(**validated_data)
        for l_name in last_names:
            LastName.objects.create(content_object=person, **l_name)
        return person

修改完成后再发起你示例的POST请求即可正常创建数据,返回结果和手动ORM操作的效果一致。如果需要支持PUT/PATCH更新嵌套的last_name,自行实现update方法处理增删改逻辑即可,和普通非多态嵌套序列化器的更新规则完全一致。

内容的提问来源于stack exchange,提问作者Oliveira Prado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 08:27:01