使用CreateAPIView创建Job时Rest调用报错:期望PK值却收到字符串
解决CreateAPIView创建ManyToMany关联对象时的PK/字符串类型错误问题
这个问题我之前也碰到过,核心原因是DRF对ManyToMany字段的默认处理逻辑——它默认期望接收关联模型的PK值(通常是整数),但你传的是字符串(比如分类的description),所以才会报类型不匹配的错误。下面给你两种针对性的解决方案:
方案一:使用SlugRelatedField匹配已有分类
如果你的请求是要关联已经存在的modelJobCategory对象,只需要修改序列化器,把category字段换成SlugRelatedField,指定用description这个唯一字段来匹配:
from rest_framework import serializers from .models import modelJob, modelJobCategory class JobSerializer(serializers.ModelSerializer): # 替换默认的PrimaryKeyRelatedField为SlugRelatedField category = serializers.SlugRelatedField( many=True, queryset=modelJobCategory.objects.all(), slug_field='description' # 用category的description字段作为匹配依据 ) class Meta: model = modelJob fields = ['id', 'category', 'description'] # 补全你的其他字段
这样你发起POST请求时,就可以直接传description字符串数组了,示例请求体:
{ "description": "后端开发岗位", "category": ["技术开发", "后端"] }
方案二:允许创建新分类同时关联Job
如果你的需求是在创建Job的同时,允许创建新的modelJobCategory对象,那需要重写序列化器的create方法,手动处理分类的创建和关联:
class JobSerializer(serializers.ModelSerializer): # 用CharField接收字符串,many=True表示支持多个分类 category = serializers.ListField(child=serializers.CharField()) class Meta: model = modelJob fields = ['id', 'category', 'description'] def create(self, validated_data): # 取出category的字符串列表 category_descriptions = validated_data.pop('category') # 创建Job对象 job = modelJob.objects.create(**validated_data) # 遍历分类描述,获取或创建对应的modelJobCategory对象 for desc in category_descriptions: category, _ = modelJobCategory.objects.get_or_create(description=desc) job.category.add(category) return job
这个版本的序列化器会自动处理“如果分类存在就关联,不存在就创建再关联”的逻辑,请求体和方案一一致即可。
额外提示
- 因为你的
modelJobCategory里description是unique=True,所以get_or_create不会创建重复的分类,刚好适配这个场景。 - 如果你用的是默认的
CreateAPIView,只需要把这个序列化器配置到视图里就行:
from rest_framework.generics import CreateAPIView from .models import modelJob from .serializers import JobSerializer class JobCreateView(CreateAPIView): queryset = modelJob.objects.all() serializer_class = JobSerializer
内容的提问来源于stack exchange,提问作者MistyD
相关产品推荐
相关产品推荐

