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

Django嵌套序列化器报错:禁止直接赋值关联集合反向侧

解决Django序列化器自定义create时的反向关联赋值错误

错误信息

TypeError: Direct assignment to the reverse side of a related set is prohibited. Use lines.set() instead.

问题原因

在CheatsheetSerializer的create方法中,遍历sections_data时,每个section字典包含了嵌套的lines数据,直接通过Section.objects.create(cheatsheet=cheatsheet, **section)创建实例时,会把lines字段传递给Section模型。但lines是Section与Line的反向关联字段(通过related_name='lines'定义),Django不允许直接对反向关联集合赋值,因此抛出错误。

解决方案

修改CheatsheetSerializer的create方法,利用已定义好的SectionSerializer来处理section及嵌套的lines数据,避免手动传递反向关联字段。

修改后的serializers.py代码:

from rest_framework import serializers
from .models import Cheatsheet, Section, Line

class LineSerializer(serializers.ModelSerializer):
    class Meta:
        model = Line
        fields = "__all__"

class SectionSerializer(serializers.ModelSerializer):
    lines = LineSerializer(many=True)

    class Meta:
        model = Section
        fields = "__all__"

    def create(self, validated_data):
        lines_data = validated_data.pop('lines')
        section = Section.objects.create(**validated_data)
        for line in lines_data:
            Line.objects.create(section=section, **line)
        return section

class CheatsheetSerializer(serializers.ModelSerializer):
    sections = SectionSerializer(many=True)

    class Meta:
        model = Cheatsheet
        fields = "__all__"

    def create(self, validated_data):
        sections_data = validated_data.pop('sections')
        cheatsheet = Cheatsheet.objects.create(**validated_data)
        
        # 修改部分:使用SectionSerializer处理每个section的数据
        for section_data in sections_data:
            section_data['cheatsheet'] = cheatsheet
            section_serializer = SectionSerializer(data=section_data)
            section_serializer.is_valid(raise_exception=True)
            section_serializer.save()
        
        return cheatsheet

说明

  • SectionSerializer已经实现了处理嵌套lines的逻辑,直接复用它可以避免重复代码,同时确保lines数据被正确处理,不会错误传递给Section模型。
  • 通过给section_data添加cheatsheet关联,再调用SectionSerializer.save(),即可完成Section及对应Line的创建,同时正确建立与Cheatsheet的关联。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 07:20:12