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

Django DRF嵌套序列化器POST请求时id字段丢失如何解决

问题根因

Django REST Framework的ModelSerializer默认会将模型自带的自增主键id设置为隐式只读字段,即使你没有在序列化器字段中显式标注read_only=True,该字段也不会被纳入可写字段范围,校验后自然不会出现在validated_data中。

解决方法

方法一:显式指定id为可写字段(适配需要嵌套传参的场景)

在GradeClassSerializer中手动声明id字段,覆盖默认的只读规则即可:

class GradeClassSerializer(CountryFieldMixin, serializers.ModelSerializer):
    """GradeClass Serializer."""
    # 显式声明id为可写字段,如果需要校验id对应实例存在,可加queryset参数
    id = serializers.IntegerField()
    class Meta:
        model = ClassGrade
        fields = ('id', 'grade', 'country', 'color_code', )

如果需要自动校验传入的id对应ClassGrade实例真实存在,可将字段声明修改为:

id = serializers.PrimaryKeyRelatedField(queryset=ClassGrade.objects.all())

修改完成后重新发送请求,validated_data['grade_level']中就可以正常获取到id字段。

方法二:优化外键关联逻辑(更符合DRF规范的推荐方案)

如果你的业务是创建Post时关联已经存在的ClassGrade实例,而非新增ClassGrade数据,完全不需要使用嵌套序列化做写入,直接用主键关联更简洁:

class PostSerializer(serializers.ModelSerializer):
    """Post Serializer"""
    owner = UserProfile(read_only=True)
    tags = TagSerializer(many=True)
    comments = CommentSerializer(many=True, read_only=True)
    slug = serializers.SlugField(read_only=True)
    # 替换原有的嵌套序列化器声明
    grade_level = serializers.PrimaryKeyRelatedField(queryset=ClassGrade.objects.all())
    
    # 配置返回响应时依然返回grade_level的完整嵌套信息
    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['grade_level'] = GradeClassSerializer(instance.grade_level).data
        return data

这种方案不需要额外处理嵌套序列化的写入逻辑,也避免了id丢失的问题。


内容的提问来源于stack exchange,提问作者Lutaaya Huzaifah Idris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:24:03