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

Django REST Framework中ViewSet更新含唯一字段模型报错

解决方案

问题根源

你当前的update方法中,初始化序列化器时没有传入要更新的instance对象,导致DRF将此次请求判定为「创建新Machine实例」而非「更新现有实例」。此时即使你把request.data['machine_number']设为原对象的值,DRF依然会触发唯一约束校验(因为原实例的machine_number已经存在于数据库中),从而抛出错误。

修正代码

修改update方法中序列化器的初始化逻辑,传入目标machine实例:

class MachineViewSet(viewsets.ViewSet):
    serializer_class = MachineSerializer
    queryset = Machine.objects.all()

    def update(self, request, pk):
        try:
            machine = Machine.objects.get(pk=pk)
            # 可选:如果不允许修改machine_number,可注释掉下面这行,后续在序列化器设置read_only
            # request.data['machine_number'] = machine.machine_number
        except Machine.DoesNotExist:
            response = build_custom_response(False, 'Machine not found', '')
            return Response(response, status=status.HTTP_404_NOT_FOUND)

        # 关键:传入instance参数,告知序列化器执行更新逻辑
        serializer = self.serializer_class(instance=machine, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            serialized_data = serializer.data
            success = True
            message = "Machine updated successfully"
            status_code = status.HTTP_200_OK
        else:
            success = False
            status_code = status.HTTP_400_BAD_REQUEST
            err_msg = '\n'
            error_list = [(serializer.errors[error][0]).capitalize() for error in serializer.errors]
            message = err_msg.join(error_list)

        data = serialized_data if 'serialized_data' in locals() else ''
        response = build_custom_response(success, message, data)
        return Response(response, status=status_code)

额外优化(可选)

如果业务上不允许修改machine_number,可以直接在序列化器中将其设为只读字段,避免后续误操作:

class MachineSerializer(serializers.ModelSerializer):
    machine_number = serializers.IntegerField(read_only=True)

    class Meta:
        model = Machine
        fields = ('id', 'machine_number', 'count', 'variety', 'lycra_draft', 'feedback', 'csp')

这样即使请求中传入machine_number,序列化器也会忽略该字段,彻底避免唯一约束冲突问题。

内容的提问来源于stack exchange,提问作者D.Karthikeyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:12:45