使用PUT更新Job数据时遇异常:预期PK值却收到字典
排查PUT更新时"Incorrect type. Expected pk value, received dict"异常的思路
这个错误的核心原因其实很明确:你的Serializer_Update_Job_Serializer在处理category这个外键字段时,默认期望接收的是外键的主键值(比如整数ID),但实际请求里传过来的是一个字典格式的完整对象数据,两者类型不匹配就触发了这个异常。
下面给你几个具体的排查和解决方向:
1. 检查序列化器的外键字段配置
默认情况下,DRF的ModelSerializer对于外键字段会自动生成PrimaryKeyRelatedField,它只认主键值。如果你的序列化器没做特殊配置,那category字段就只能接收类似1这样的ID值,传字典肯定会报错。
举个默认序列化器的例子(这种写法就会触发你遇到的问题):
class Serializer_Update_Job_Serializer(ModelSerializer): class Meta: model = modelJob fields = ['id', 'category', 'description']
如果你的业务需要接收完整的category字典来更新(甚至自动创建不存在的分类),可以修改序列化器:
- 要是只想通过分类名称匹配关联,用
SlugRelatedField:
class Serializer_Update_Job_Serializer(ModelSerializer): category = SlugRelatedField(slug_field='name', queryset=modelJobCategory.objects.all()) class Meta: model = modelJob fields = ['id', 'category', 'description']
- 如果需要支持创建新分类并关联,用嵌套序列化器+重写
update方法:
class JobCategorySerializer(ModelSerializer): class Meta: model = modelJobCategory fields = ['name', 'other'] class Serializer_Update_Job_Serializer(ModelSerializer): category = JobCategorySerializer() class Meta: model = modelJob fields = ['id', 'category', 'description'] def update(self, instance, validated_data): # 提取分类数据 category_data = validated_data.pop('category') # 查找已有分类或创建新分类 category, _ = modelJobCategory.objects.get_or_create(**category_data) # 更新岗位的分类关联 instance.category = category # 更新其他字段 instance.description = validated_data.get('description', instance.description) instance.save() return instance
2. 检查前端请求的参数格式
如果你的序列化器就是默认的主键接收模式,那要确认前端PUT请求的category字段是不是传的主键值,而不是完整的对象字典。
正确的请求体应该是这样:
{ "description": "更新后的岗位描述", "category": 1 // 这里是分类的ID,不是字典 }
而不是这种会报错的格式:
{ "description": "更新后的岗位描述", "category": {"name": "后端开发", "other": "技术岗"} }
3. 检查视图类的更新逻辑
如果你用了UpdateAPIView或者ModelViewSet,默认更新逻辑没问题,但如果自己重写了update方法,要确保没有把字典直接赋值给外键字段——这种错误操作也会触发类型不匹配的异常。
总结下来,最常见的问题就是序列化器外键字段的期望类型和前端传入的数据类型不匹配,从这两个方向入手排查,很快就能解决问题啦。
内容的提问来源于stack exchange,提问作者MistyD
相关产品推荐
相关产品推荐

