Django orm - 如何在不同日期的查询中获取不同的字段项

时间:2018-06-06 20:27:18

标签: python django postgresql django-queryset

我有以下型号:

class Event(models.Model):
    date = models.DateTimeField()
    event_type = models.ForeignKey('EventType')

class EventType(models.Model):
    name = models.CharField(unique=True)

我正在尝试获取所有日期的列表,以及该日期可用的事件类型。

列表中的每个项目都是一个包含两个字段的字典:dateevent_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')

但是这将在给定日期内为每种事件类型提供一个条目。我需要在每个日期内汇总一个列表。

有没有办法构建一个查询集来执行此操作?如果没有,我将如何通过其他方式来达到相同的结果呢?

1 个答案:

答案 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在线性时间内工作,并返回行数。