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

在Django Rest Framework的CourseViewSet中更新关联Prerequisite

实现DRF中课程关联前置条件的嵌套更新(类似Admin TabularInline)

当前你的序列化器仅支持读取关联的Prerequisite数据,无法在更新Course时同步修改关联的前置条件。要实现类似Django Admin TabularInline的关联更新,无需单独创建Prerequisite视图,只需调整序列化器并添加更新逻辑即可,具体步骤如下:

1. 修改序列化器,支持嵌套读写

替换原CourseSerializer中的SerializerMethodField为可写的嵌套序列化器,并添加update方法处理关联数据的增删改:

class CourseSerializer(serializers.ModelSerializer):
    # 替换只读的SerializerMethodField为可写的嵌套序列化器
    prerequisite = PrerequisiteSerializer(many=True)

    class Meta:
        model = models.Course
        fields = "__all__"

    def update(self, instance, validated_data):
        # 提取传入的前置条件数据,若无则跳过关联更新
        prerequisites_data = validated_data.pop('prerequisite', None)
        
        # 先更新Course自身的字段
        instance = super().update(instance, validated_data)
        
        if prerequisites_data:
            # 获取当前课程已有的所有前置条件ID
            existing_prereq_ids = instance.course_prerequisite.values_list('id', flat=True)
            # 收集传入数据中带ID的前置条件ID
            incoming_prereq_ids = [item['id'] for item in prerequisites_data if 'id' in item]
            
            # 删除不在传入列表中的前置条件(模拟TabularInline的删除操作)
            instance.course_prerequisite.exclude(id__in=incoming_prereq_ids).delete()
            
            # 遍历传入数据,更新现有前置条件或创建新的
            for prereq_data in prerequisites_data:
                prereq_id = prereq_data.get('id')
                if prereq_id and prereq_id in existing_prereq_ids:
                    # 存在ID则更新对应前置条件
                    Prerequisite.objects.filter(id=prereq_id, course=instance).update(**prereq_data)
                else:
                    # 无ID则创建新的前置条件关联到当前课程
                    Prerequisite.objects.create(course=instance, **prereq_data)
        
        return instance

2. 调整视图的update方法(如需要)

如果你的CourseViewSet继承自ModelViewSet,默认的update方法已能满足需求,无需额外修改。如果是自定义的update方法,确保传递请求数据并启用部分更新:

def update(self, request, pk=None):
    course = get_object_or_404(Course, slug=pk)
    # partial=True允许只更新部分字段
    serializer = serializers.CourseSerializer(instance=course, data=request.data, partial=True)
    serializer.is_valid(raise_exception=True)
    serializer.save()
    return Response(serializer.data, status=status.HTTP_200_OK)

3. 测试更新请求

发送PATCH请求到课程详情接口,请求体示例如下(更新ID为1的Prerequisite标题):

{
    "prerequisite": [
        {
            "id": 1,
            "title": "Updated Introduction to Python Basics"
        }
    ]
}

这样就能在更新课程的同时,同步修改关联的Prerequisite数据,实现类似Admin TabularInline的关联更新效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:10:15