Django DRF创建嵌套关联报错:禁止直接赋值关联集合反向端
问题解决:DRF嵌套关联POST请求报错处理
问题原因
你的MeetingSerializer中给startups字段指定了source='associated_startups',DRF会把请求里的startups数据解析后存入validated_data的associated_startups键下,但你在create方法里只移除了startups键,导致associated_startups留在validated_data中。DRF会尝试直接给meeting_instance.associated_startups赋值,而associated_startups是反向关联集合,不允许直接赋值,必须用set()方法,因此触发报错。
修复方案
修改MeetingSerializer的create方法,把validated_data.pop('startups', [])改成validated_data.pop('associated_startups', []),确保移除DRF解析后的关联数据键,避免自动赋值:
def create(self, validated_data): # 移除source对应的关联数据键 startups_data = validated_data.pop('associated_startups', []) meeting_instance = Meetings.objects.create(**validated_data) for startup_data in startups_data: startup_instance = Startup_info.objects.get(startup_id=startup_data.pop('startup')) MeetingStartup.objects.create( meeting=meeting_instance, starting_time=startup_data['starting_time'], duration=startup_data['duration'], startup=startup_instance ) return meeting_instance
额外优化建议
- 简化实例查询:如果请求中
startup字段传的是主键值,可以修改MeetingStartupSerializer,让DRF自动处理实例查询:
class MeetingStartupSerializer(serializers.ModelSerializer): startup = serializers.PrimaryKeyRelatedField(queryset=Startup_info.objects.all()) class Meta: model = MeetingStartup fields = ['meeting', 'starting_time', 'duration', 'startup'] read_only_fields = ['meeting']
之后create方法可以简化为:
for startup_data in startups_data: MeetingStartup.objects.create(meeting=meeting_instance, **startup_data)
- 规范模型命名:建议将模型类名改为单数形式(
Meeting而非Meetings),符合Django模型命名规范。
内容的提问来源于stack exchange,提问作者Himanshu
相关产品推荐
相关产品推荐

