使用多个字段用计数注释 Django 查询集
Annotating Django querysets with counts using multiple fields
这是我的模型的简化版本:
class Flight(models.Model):
airline = models.CharField(max_length=100)
origin = models.CharField(max_length=4)
destination = models.CharField(max_length=4)
我想做的是按 Flight
对象的某些字段的共同值对这些对象进行分组,并用相应的航班计数对这些组进行注释,如文档 here 中所述。
我知道在只考虑一个领域时该怎么做。例如,使用
Flight.objects.values('airline').annotate(Count('id')).order_by('-id__count')
我得到这样的结果:
[{'airline': 'First Airlines', 'id__count': 21},
{'airline': 'Air Second', 'id__count': 6},
{'airline': 'Third Airways', 'id__count': 3}, ...]
这意味着有 21 个 Flight
个对象的 airline
字段是 'First Airlines'
,依此类推。
但是我如何归纳以计算多个字段并将其组合成一个带注释的查询集,将来自不同字段的值视为同一个字段?
例如,假设我有 3 个从洛杉矶到纽约的航班,还有 2 个 return 航班从另一个方向(有 3 个 Flight
个对象,起点 'LAX'
和目的地 'JFK'
,以及 2 个 Flight
个对象,起点 'JFK'
,目的地 'LAX'
)。我怎样才能得到这个:
[{'airport': 'LAX', 'id__count': 5},
{'airport': 'JFK', 'id__count': 5}]
好吧,您不能在单个查询中完成。需要先标注起点,再标注终点,最后总结:
data1 = Flight.objects.values('origin').annotate(Count('id'))
data2 = Flight.objects.values('destination').annotate(Count('id'))
data = {}
for airport in { x for x in data1.keys() + data2.keys() }:
data[airport] = data1.get(airport, 0) + data2.get(airport, 0)
这是我的模型的简化版本:
class Flight(models.Model):
airline = models.CharField(max_length=100)
origin = models.CharField(max_length=4)
destination = models.CharField(max_length=4)
我想做的是按 Flight
对象的某些字段的共同值对这些对象进行分组,并用相应的航班计数对这些组进行注释,如文档 here 中所述。
我知道在只考虑一个领域时该怎么做。例如,使用
Flight.objects.values('airline').annotate(Count('id')).order_by('-id__count')
我得到这样的结果:
[{'airline': 'First Airlines', 'id__count': 21},
{'airline': 'Air Second', 'id__count': 6},
{'airline': 'Third Airways', 'id__count': 3}, ...]
这意味着有 21 个 Flight
个对象的 airline
字段是 'First Airlines'
,依此类推。
但是我如何归纳以计算多个字段并将其组合成一个带注释的查询集,将来自不同字段的值视为同一个字段?
例如,假设我有 3 个从洛杉矶到纽约的航班,还有 2 个 return 航班从另一个方向(有 3 个 Flight
个对象,起点 'LAX'
和目的地 'JFK'
,以及 2 个 Flight
个对象,起点 'JFK'
,目的地 'LAX'
)。我怎样才能得到这个:
[{'airport': 'LAX', 'id__count': 5},
{'airport': 'JFK', 'id__count': 5}]
好吧,您不能在单个查询中完成。需要先标注起点,再标注终点,最后总结:
data1 = Flight.objects.values('origin').annotate(Count('id'))
data2 = Flight.objects.values('destination').annotate(Count('id'))
data = {}
for airport in { x for x in data1.keys() + data2.keys() }:
data[airport] = data1.get(airport, 0) + data2.get(airport, 0)