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

Django DRF单请求为单个候选人添加多个关联技能解决多实例赋值报错

问题原因

你的报错是默认ModelSerializer仅支持单次创建一条CandidateSkill关联记录导致的:skills是单外键字段,只能关联单个Skill实例,当请求传入多个技能ID时,默认序列化逻辑无法将多个实例赋值给该字段,因此触发错误。

解决方案

1. 调整序列化器,支持批量接收技能ID并重写创建逻辑

from rest_framework import serializers
from jobs.models import Skill
from .models import CandidateSkill

class CandidateSkillSerializer(serializers.ModelSerializer):
    # 接收多个技能ID的列表字段,仅写入用
    skills = serializers.ListField(
        child=serializers.PrimaryKeyRelatedField(queryset=Skill.objects.all()),
        write_only=True
    )
    # 只读字段,返回关联的技能名称用于展示
    skill_name = serializers.StringRelatedField(source='skills', read_only=True)

    class Meta:
        model = CandidateSkill
        fields = ["id", "candidate", "skills", "skill_name"]
    
    def create(self, validated_data):
        # 取出校验通过的技能列表和候选人ID
        skill_list = validated_data.pop('skills')
        candidate = validated_data['candidate']
        # 批量生成关联记录
        skill_objs = [
            CandidateSkill(candidate=candidate, skills=skill_item) 
            for skill_item in skill_list
        ]
        # 批量写入数据库,提升性能
        CandidateSkill.objects.bulk_create(skill_objs)
        # 返回第一条创建的记录(可根据需求调整返回逻辑)
        return skill_objs[0]

2. 调整视图,支持批量创建后返回全量关联技能

from rest_framework import generics, status
from rest_framework.response import Response
from .models import CandidateSkill
from .serializers import CandidateSkillSerializer

class CandidateSkillList(generics.ListCreateAPIView):
    serializer_class = CandidateSkillSerializer
    queryset = CandidateSkill.objects.all()

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        # 查询当前候选人的所有关联技能返回
        candidate = serializer.validated_data['candidate']
        candidate_skills = self.get_queryset().filter(candidate=candidate)
        return Response(
            self.get_serializer(candidate_skills, many=True).data, 
            status=status.HTTP_201_CREATED
        )

3. (可选)模型层添加联合唯一约束,避免重复插入相同关联

class CandidateSkill(models.Model):
    candidate = models.ForeignKey(Candidate, on_delete=models.CASCADE,related_name="skills",)
    skills = models.ForeignKey("jobs.Skill", on_delete=models.CASCADE)

    class Meta:
        # 确保同一个候选人不会重复关联同一个技能
        constraints = [
            models.UniqueConstraint(fields=['candidate', 'skills'], name='unique_candidate_skill')
        ]
请求示例

发送POST请求到接口时,请求体格式如下即可实现单请求批量添加关联技能:

{
  "candidate": 1,
  "skills": [2, 3, 5, 8]
}

以上示例将为ID为1的候选人关联ID为2、3、5、8的四个技能。

内容的提问来源于stack exchange,提问作者Muhammad Shehzad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 07:06:03