Django REST Framework序列化器create方法profile字段KeyError问题求助
问题根因
你在GetStaffPostSerializer中将profile和jobs字段设置为read_only=True,该属性声明字段仅参与序列化(即接口返回数据时生成对应字段),不会参与反序列化(即不会解析前端提交的POST参数)。因此你提交的profile和jobs参数不会被DRF写入validated_data字典,调用pop方法时自然触发KeyError。
同时你原有create方法还存在两个隐藏问题:
- 最终返回的是
profile实例而非创建的GetStaffPost实例,会导致接口返回数据不符合预期 - 多对多字段手动循环
add效率偏低,可以直接用set方法批量赋值
解决方案
步骤1:先定义关联模型的序列化器
你需要先准备Profile和Job模型的序列化器,用于GET请求时返回全量字段,可根据你的业务需求调整返回字段:
# 新增两个关联模型的序列化器 class ProfileSerializer(serializers.ModelSerializer): class Meta: model = Profile # 可替换为你实际需要返回的Profile字段列表 fields = "__all__" class JobSerializer(serializers.ModelSerializer): class Meta: model = Job # 可替换为你实际需要返回的Job字段列表 fields = "__all__"
步骤2:修改GetStaffPostSerializer逻辑
调整字段属性,并重写序列化方法实现读写分离,同时修复create方法问题:
class GetStaffPostSerializer(serializers.ModelSerializer): # 移除read_only属性,新增queryset参数声明可查询范围,支持接收主键参数 profile = serializers.PrimaryKeyRelatedField(queryset=Profile.objects.all()) jobs = serializers.PrimaryKeyRelatedField(queryset=Job.objects.all(), many=True) class Meta: model = GetStaffPost fields = "__all__" # 重写序列化返回逻辑,GET请求时自动替换为全量嵌套数据 def to_representation(self, instance): data = super().to_representation(instance) data["profile"] = ProfileSerializer(instance=instance.profile).data data["jobs"] = JobSerializer(instance=instance.jobs.all(), many=True).data return data def create(self, validated_data): # 仅需弹出多对多字段,profile可直接传入create方法 jobs = validated_data.pop("jobs") post = GetStaffPost.objects.create(**validated_data) # 批量赋值多对多字段 post.jobs.set(jobs) # 返回创建的帖子实例而非profile return post
验证效果
修改后即可满足你的需求:
- POST请求时仍然传入
profile(主键值)和jobs(主键列表),和你现有传参逻辑完全一致 - GET请求时会自动返回
profile和jobs的全量字段,无需额外修改前端请求逻辑
内容的提问来源于stack exchange,提问作者hyowon
相关产品推荐
相关产品推荐

