Skip to main content
 首页 » 编程设计

python之Django 按多个字段分组

2024年12月31日21insus

我想将此 SQL 请求转换为 Django View :

SELECT color, shape, eyes, count(1) FROM animals WHERE master_id = 1 GROUP BY color, shape, eyes  

为了做到这一点,我尝试过:

animals = Animals.objects.filter(id=1).values('color', 'shape', 'eyes').annotate(ct=Count('color'), dg=Count('shape'), br=Count('eyes')) 

然后在结果上循环以找到每个(不是很优化)的计数,但结果并不好。这是我想要的分组方式,但不关心 id。

编辑:

<QuerySet [ 
    { 'color': brown, 'shape': blabla, 'eyes': toto, 'ct': 2 }, 
    { 'color': black, 'shape': blabla, 'eyes': toto, 'ct': 1 }, 
    { 'color': yellow, 'shape': xxxxx, 'eyes': ok, 'ct': 4 } 
]> 

第二次编辑:

如果我尝试这样做:

Animals.objects.filter( 
    master_id=1 
).values('color', 'shape', 'eyes').annotate( 
    ct=Count('id') 
).order_by('color', 'shape', 'eyes') 

我有这个结果没有计数:

<QuerySet [ 
    { 'color': brown, 'shape': blabla, 'eyes': toto}, 
    { 'color': black, 'shape': blabla, 'eyes': toto}, 
    { 'color': yellow, 'shape': xxxxx, 'eyes': ok } 
]> 

最后编辑:

Animal 表没有 count 或 ct 列,但我的结果中需要它

请您参考如下方法:

一个完整的等效查询是:

Animals.objects.filter( 
    master_id=1 
).values('color', 'shape', 'eyes').annotate( 
    ct=Count('id') 
).order_by('color', 'shape', 'eyes')

这将产生一个包含字典的 QuerySet,例如:

<QuerySet [ 
    { 'color': 0, 'shape': 2, 'eyes': 1, 'ct': 1 }, 
    { 'color': 0, 'shape': 3, 'eyes': 3, 'ct': 4 }, 
    { 'color': 1, 'shape': 0, 'eyes': 0, 'ct': 2 }, 
    { 'color': 2, 'shape': 2, 'eyes': 1, 'ct': 5 }, 
]> 

例如:

>>> Animals.objects.create(color='foo', shape='bar', eyes='brown', master_id=1) 
<Animal: Animal object (2)> 
>>> Animals.objects.create(color='foo', shape='bar', eyes='brown', master_id=1) 
<Animal: Animal object (3)> 
>>> Animals.objects.create(color='foo', shape='bar', eyes='blue', master_id=1) 
<Animal: Animal object (4)> 
>>> Animals.objects.create(color='foo', shape='rectangle', eyes='brown', master_id=1) 
<Animal: Animal object (5)> 
>>> Animals.objects.create(color='red', shape='rectangle', eyes='brown', master_id=1) 
<Animal: Animal object (6)> 
>>> Animals.objects.filter( 
...     master_id=1 
... ).values('color', 'shape', 'eyes').annotate( 
...     ct=Count('id') 
... ).order_by('color', 'shape', 'eyes') 
<QuerySet [{'color': 'foo', 'shape': 'bar', 'eyes': 'blue', 'ct': 1}, {'color': 'foo', 'shape': 'bar', 'eyes': 'brown', 'ct': 2}, {'color': 'foo', 'shape': 'rectangle', 'eyes': 'brown', 'ct': 1}, {'color': 'red', 'shape': 'rectangle', 'eyes': 'brown', 'ct': 1}]>