Django Макс. Агрегация даты и времени - PullRequest
0 голосов
/ 05 марта 2020

Каков наилучший способ получения максимального значения даты / времени для связанных объектов связанных объектов экземпляра Django? Мне нужно это значение в качестве свойства экземпляра.

Например, для этих моделей

class Show(Model):
    is_live = BooleanField()
    ...

class Season(Model):
    show = ForeignKeyField(Show, on_delete=CASCADE, related_name='seasons')
    is_live = BooleanField()
    ...

class Episode(Model):
    season = ForeignKeyField(Season, on_delete=CASCADE, related_name='episodes')
    is_live = BooleanField()
    live_date = DateTimeField(blank=True, null=True)
    ...

Как я могу получить самый последний эпизод live_date экземпляра шоу, включая только эпизоды где сезон is_live == True и эпизод is_live == True?

Я пробовал это в модели Show:

@property
def max_episode_live_date(self)
    return self.seasons.filter(
        is_live=True
     ).aggregate(
        max_=Max(
            'episodes__live_date',
            filter=Q(episodes__is_live=True)
        )
    ).get('max_')

, но я получаю эту ошибку AttributeError : у объекта 'str' нет атрибута 'tzinfo'

Я пытался использовать Django выражения SubQuery ,

@property
def max_episode_live_date(self)
    episodes = Episode.objects.filter(
        is_live=True,
        season=OuterRef('pk')
    ).values('live_date')

    return self.seasons.filter(
        is_live=True
    ).aggregate(
        max_=Max(Subquery(episodes))
    ).get('max_')

, но потом получаю django .db.utils.OperationalError: (1242, «Подзапрос возвращает более 1 строки»)

Я полагаю, это связано с некоторыми эпизодами, содержащими ноль live_date, но я Я не уверен, как обойти. Любое понимание будет оценено.

1 Ответ

0 голосов
/ 05 марта 2020
@property
def max_episode_live_date(self)
    return self.seasons.filter(
        is_live=True
     ).aggregate(
        max_=Max(
            'episodes__live_date',
            filter=Q(episodes__is_live=True)
        )
    ).get('max_')

Будет выполнено SQL

"SELECT MAX(CASE WHEN `episode`.`is_live` is true THEN `episode`.`live_date` ELSE NULL END) AS `max_`" 

. Результатом будет строка или None. Когда строка преобразуется в DateTime с часовым поясом, происходит ошибка. Я думаю, что это может быть ошибка Django.

...