【问题标题】:Django distinct returns more records than countDjango distinct 返回的记录多于计数
【发布时间】:2025-11-24 10:55:02
【问题描述】:

以下显示不同计数为 2247

In [6]: VirtualMachineResources.objects.all().values('machine', 'cluster')
   ...: .distinct().count()                                               
Out[6]: 2247

但是当我遍历它时,它返回的方式比它应该的要多:

In [4]: a = [] 
   ...: for resource in VirtualMachineResources.objects.all().values('mach
   ...: ine', 'cluster').distinct(): 
   ...:     if resource['cluster']: 
   ...:         a.append(resource['cluster']) 
   ...:          
   ...:                                                                   

In [5]: len(a)                                                            
Out[5]: 96953

鉴于记录的集群字段为空,当我遍历查询集时,我可以看到同一台机器的很多重复没有集群值,但我希望只有一次。

for resource in VirtualMachineResources.objects.all().values('machine', 'cluster').distinct(): 
    print(resource['machine'], resource['cluster'])

打印...

server1
server1
server1

这是一个 postgres 数据库。有任何想法吗? 在 google 和this 上进行更多挖掘似乎相关?

更新: 创建了一个 Django 问题here

【问题讨论】:

  • 我看到没有集群值的机器不断出现...
  • 它在您提供的链接中提到:“问题是 QuerySet 类上的 count 方法不知道 ValuesQuerySet 子类的 _fields 字段。因此,它的作用与values() 根本没有被使用。附加的补丁通过将计数方法从 QuerySet 复制并特化到 ValuesQuerySet 来解决问题。如果没有 _fields 存在(在不同的情况下),则使用原始键QuerySet 计数方法。补丁有点幼稚;重构 QuerySet 计数方法可能更可取,但我不确定首选的 s
  • 也许你可以创建一个自定义的Manager 并添加你自己的查询集。

标签: django django-orm


【解决方案1】:

您有一个定义的VirtualMachineResources.Meta.ordering 混淆了ORM,因为在使用DISTINCT 时,列的排序必须出现在SELECT 子句中。使用.count()时恰好清除了排序。

长存储短,添加.order_by()Meta.ordering 放在您正在迭代的查询集上,您应该很高兴。没有好的方法可以生成一个不包括 Django ORM 上的排序字段的 DISTINCT,因为这需要一个复杂的子查询下推,详见 #24218

顺便说一句,当您没有尽快收到对您的问题的回复时,请避免将 Django 的票务跟踪器作为第二层支持渠道。

【讨论】: