Django模型 - 获取唯一值列表

81

我试图获取一个唯一的外键列表,我写了以下代码:

my_ids = Entity.objects.values('foreign_key').distinct()

但是我只得到了不重复的外键列表... 我错过了什么吗?

谢谢!

4个回答

70

据我所知,对于MySQL数据库,将参数传递给distinct无效。

这个可以工作,并且只返回一个对象:

Entity.objects.order_by('foreign_key').values('foreign_key').distinct()


7
我在使用Postgres9.1数据库和Django==1.5.5时遇到了相同的问题,添加order_by有所帮助 - 很蠢... - kev

69

也许你想选择这个:

Entity.objects.order_by().values_list('foreign_key', flat=True).distinct()

19
如果不使用order_by('foreign_key'),那么就会出错。例如,在M2M(Postgres、Django 1.8)中。 - andilabs

51
Entity.objects.values_list('foreign_key', flat=True).distinct().order_by()

distinct在没有order_by的情况下无法工作,Django文档中已经解释过:

order_by() 调用中使用的任何字段都包含在 SQL SELECT 列中。当与 distinct() 结合使用时,这有时会导致意外结果。如果按照相关模型中的字段排序,则这些字段将被添加到所选列中,它们可能使本来重复的行看起来不同。由于额外的列不出现在返回的结果中(它们只是为了支持排序而存在),因此有时看起来好像返回了非唯一结果。同样地,如果使用 values() 查询限制所选的列,则任何 order_by()(或默认模型排序)中使用的列仍将参与并可能影响结果的唯一性。这里的道德是,如果您正在使用 distinct(),请小心按相关模型排序。同样,在同时使用 distinct()values() 时,请小心按不在 values() 调用中的字段排序。

3
哇塞!奖金:order_by() 实际上并不排序,但解决了去重的问题。这太疯狂了。 - Csaba Toth
这个可行吗?看起来distinct和order by需要使用MIN或MAX来得到正确的排序,因此需要一个两列的解决方案。我猜order by只是按照values_list字段排序,这可能不是模型的默认排序顺序。正确的解决方案是编写自定义查询:select value,min(sequence) as sequence from some_table group by value order by sequence; - Paul Kenjora
1
.order_by() 不带参数时会清除查询集上的任何默认或现有排序。 - Tim Tisdall

9
Entity.objects.order_by('foreign_key').distinct('foreign_key')

如果您已经有一个列表,那么将其转换为set()以获取不同的值。

将其转换为集合不是一个好主意,因为与set()相比,所有内容都会填充到内存中,而queryset在评估之前不会加载。而将其转换为列表也会评估queryset吗? - vijay shanker
1
集合是无序的,因此您将取消order_by,而在某些情况下这很重要。 - Paul Kenjora

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接