Django序列化器出现DoesNotExist错误,求基于给定模型与序列化器的解决方案
搞定Django序列化器的
DoesNotExist错误! 嘿,我来帮你排查这个让人头疼的DoesNotExist: matching query does not exist错误!先看你给的代码,问题大概率出在ScenarioSerializer的create方法里处理tasks的逻辑上。
为啥会报错?
你现在的create方法只是把tasks从验证数据里取出来,但根本没正确处理这些任务数据——要么是想关联数据库里已有的Task,但没去查对应的实例;要么是想创建新Task,却没写创建逻辑。这就导致Django找不到匹配的Task对象,直接抛出了DoesNotExist异常。
分情况给你修复方案
根据你的业务需求,分两种场景来改:
场景1:关联数据库里已有的Task
如果前端传的是Task的id列表(比如[{"id": 1}, {"id": 2}]),那你得用这些id去数据库里查对应的Task实例,再关联到Scenario上:
def create(self, validated_data): # 加个默认空列表,避免前端不传tasks时炸KeyError tasks_data = validated_data.pop('tasks', []) instance = Scenario.objects.create(**validated_data) for task_data in tasks_data: try: # 通过id找已有Task task = Task.objects.get(id=task_data['id']) instance.tasks.add(task) except Task.DoesNotExist: # 这里可以根据业务选:跳过这个任务、抛明确的验证错误,或者直接创建新的 raise serializers.ValidationError(f"找不到id为{task_data['id']}的任务哦") return instance
场景2:创建新Task并关联
如果前端传的是完整的Task字段(比如[{"name": "写接口文档", "content": "xxx"}]),那得先创建新的Task实例,再关联到Scenario:
def create(self, validated_data): tasks_data = validated_data.pop('tasks', []) instance = Scenario.objects.create(**validated_data) for task_data in tasks_data: # 用get_or_create避免重复创建相同任务,也可以直接用create task, _ = Task.objects.get_or_create(**task_data) instance.tasks.add(task) return instance
额外的偷懒小技巧
如果你只是想关联已有Task,其实可以不用自己写查询逻辑——把序列化器里的tasks字段换成PrimaryKeyRelatedField,DRF会自动帮你验证id的有效性:
class ScenarioSerializer(serializers.ModelSerializer): # 替换原来的TaskSerializer tasks = serializers.PrimaryKeyRelatedField( many=True, queryset=Task.objects.all(), required=False ) class Meta: model = Scenario fields = '__all__' def create(self, validated_data): tasks = validated_data.pop('tasks', []) instance = Scenario.objects.create(**validated_data) # 直接批量添加就行 instance.tasks.add(*tasks) return instance
这样既简洁又不容易出错,完美!
内容的提问来源于stack exchange,提问作者Thinker
相关产品推荐
相关产品推荐

