Django 2.0中union生成的QuerySet调用get()报MultipleObjectsReturned异常
我来帮你拆解这个问题的原因和解决办法:
为什么get()会抛出MultipleObjectsReturned异常?
这是Django 2.0中union()生成的CompoundQuerySet的一个已知行为问题。当你调用get()时,Django内部的计数逻辑并没有正确处理UNION的去重特性——它可能直接将两个子查询中匹配主键的对象数量相加,而不是基于去重后的结果集来计数。哪怕最终去重后的结果里只有一个匹配的对象,Django也会错误地认为找到了多个,从而抛出异常。
用字符串查找UUID是否正确?
完全正确!Django的UUIDField原生支持字符串格式的UUID值,它会自动完成字符串到UUID对象的转换,不需要额外处理格式,你当前的写法没有问题。
解决办法
你可以用以下两种方式替代get()来避开这个问题:
- 使用
filter()+first()(推荐):
need = needs.filter(pk="3fbdcc49-2f06-46ea-a0a3-587ac5aaf50f").first()
这个写法和get()逻辑一致:找到匹配的第一个对象,若没有匹配项则返回None,而且不会因为CompoundQuerySet的计数bug抛出异常。
- 转换为列表后遍历查找:
如果你的结果集数据量不大,也可以先把queryset转为普通列表,再通过遍历找到目标对象:
need = next((n for n in needs if n.pk == "3fbdcc49-2f06-46ea-a0a3-587ac5aaf50f"), None)
另外补充一点:Django的union()默认已经启用了去重(相当于SQL的UNION DISTINCT),除非你传入了all=True参数,所以不需要额外设置去重逻辑。
内容的提问来源于stack exchange,提问作者harrouet
相关产品推荐
相关产品推荐

