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

Django更新嵌套对象时如何将缺失的pk字段添加到序列化器中

解决方案

第一步:修改PlanEventUpdateSerializer配置

默认DRF的ModelSerializer会将模型主键字段设置为只读,反序列化后validated_data不会包含该字段,需要手动显式声明id为可写字段并加入字段列表:

class PlanEventUpdateSerializer(serializers.ModelSerializer):
    # 显式声明id字段,取消默认只读约束
    id = serializers.CharField(max_length=100)
    class Meta:
        model = PlanEvent
        fields = ('id', 'done', 'title')

修改后只要前端提交的events数据中携带每条事件的id,你写的删除对比逻辑就能正常获取item['id']执行判断。

第二步:补充完整update方法逻辑

你当前只写了删除逻辑,建议补充已有事件更新、新增事件的逻辑保证功能完整:

class PlanUpdateSerializer(serializers.ModelSerializer):
    events = PlanEventUpdateSerializer(many=True)
    class Meta:
        model = Plan
        fields  = ('name',)

    def update(self, instance, validated_data):
        events_validated_data = validated_data.pop('events')
        # 先更新Plan主表字段
        instance.name = validated_data.get('name', instance.name)
        instance.save()

        existing_events = list(instance.events.all())
        existing_event_map = {event.id: event for event in existing_events}
        submitted_event_ids = [item['id'] for item in events_validated_data]

        # 删除未提交的旧事件
        for event in existing_events:
            if event.id not in submitted_event_ids:
                event.delete()
        
        # 更新已有事件、新增提交的新事件
        for event_data in events_validated_data:
            event_id = event_data['id']
            if event_id in existing_event_map:
                # 更新已存在的事件
                event = existing_event_map[event_id]
                event.done = event_data.get('done', event.done)
                event.title = event_data.get('title', event.title)
                event.save()
            else:
                # 新增事件,关联当前Plan实例
                PlanEvent.objects.create(plan=instance, **event_data)
        
        return instance
注意事项
  • 前端提交events数组时必须携带对应事件的id字段,如果是新增的事件也需要生成唯一id同步提交,匹配你模型中PlanEvent.id为手动指定主键的设计
  • 如果不需要前端生成新增事件id,可以将PlanEvent.id的字段属性修改为default=uuid.uuid4, editable=False,对应序列化器中id字段设置为required=False,新增时就不需要传id参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:36:06