我有以下型号:
class Event(models.Model):
date = models.DateTimeField()
event_type = models.ForeignKey('EventType')
class EventType(models.Model):
name = models.CharField(unique=True)
我正在尝试获取所有日期的列表,以及该日期可用的事件类型。
列表中的每个项目都是一个包含两个字段的字典:date
和event_types
,它们是该日期可用的不同事件类型的列表。
目前我已经想出了一个查询来获取所有不同日期的列表,但这只是我想要做的事情的一半:
query = Event.objects.all().select_related('event_type')
results = query.distinct('date').order_by('date').values_list('date', flat=True)
现在我可以稍微更改一下,以获取所有不同日期+ event_type组合的列表:
query = Event.objects.all().select_related('event_type')
results = query.order_by('date').distinct('date', 'event_type').values_list('date', 'event_type__name')
但是这将在给定日期内为每种事件类型提供一个条目。我需要在每个日期内汇总一个列表。
有没有办法构建一个查询集来执行此操作?如果没有,我将如何通过其他方式来达到相同的结果呢?
答案 0 :(得分:1)
您可以使用groupby
的 itertools
功能执行此类汇总。要求元素以“石斑鱼标准”的形式出现在“块”中。但这是这种情况,因为您使用order_by
。
我们可以这样写:
from itertools import groupby
from operator import itemgetter
query = (Event.objects.all.select_related('event_type')
.order_by('date', 'event_type')
.distinct('date', 'event_type')
.values_list('date', 'event_type__name'))
result = [
{ 'date': k, 'datetypes': [v[1] for v in vs]}
for k, vs in groupby(query, itemgetter(0))
]
您还可以按标准顺序使用'event_type'
。
这将导致类似:
[{'date': datetime.date(2018, 5, 19), 'datetypes': ['Famous person died',
'Royal wedding']},
{'date': datetime.date(2018, 5, 24), 'datetypes': ['Famous person died']},
{'date': datetime.date(2011, 5, 25), 'datetypes': ['Important law enforced',
'Referendum']}]
(基于5月最后几天的快速维基百科扫描)。
groupby
在线性时间内工作,并返回行数。