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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 07:04:20