Django orm - как получить разные элементы поля в запросе разных дат - PullRequest
0 голосов
/ 06 июня 2018

У меня есть следующие модели:

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)

Теперь я могу немного изменить это, чтобы получить список всех различных комбинаций типа date + 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 голосов
/ 06 июня 2018

Вы можете выполнить такой агрегат с помощью функции groupby, равной itertools.Требуется, чтобы элементы появлялись в виде «кусков» по ​​отношению к «критериям группировщика».Но здесь дело обстоит так, поскольку вы используете order_by.

Таким образом, мы можем записать его следующим образом:

<b>from itertools import groupby
from operator import itemgetter</b>

query = (Event.objects.all.select_related('event_type')
                         .order_by('date'<b>, 'event_type'</b>)
                         .distinct('date', 'event_type')
                         .values_list('date', 'event_type__name'))
result = [
    { 'date': k, 'datetypes': [v[1] for v in vs]}
    for k, vs in <b>groupby(query, itemgetter(0))</b>
]

Вы также лучше используете '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']}]

(на основе быстрого сканирования Википедии последних дней мая).

groupby работает в линейном времени сколичество возвращаемых строк.

...