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
相关产品推荐
相关产品推荐

