Как объединить поля даты и времени в поле DateTime в выражении Django F - PullRequest
0 голосов
/ 17 июня 2019

Я должен получить разницу между двумя datetime полями, но одно поле является чистым полем даты и времени, а другое - комбинацией даты и времени. Я попробовал это:

    qs = Foo.objects.filter(
        bar__baz_id=self.kwargs['baz_pk'],
    )
    start_datetime = ExpressionWrapper((F('x__date') + F('x__start')), output_field=DateTimeField())
    qs = qs.annotate(start_datetime=start_datetime)
    before_start_wrapper = ExpressionWrapper(
        F('start') - F('start_datetime'),   # 'start' is datetime field on Foo, start_datetime is annotated field on Foo
        output_field=DateTimeField()
    )
    before_start = Extract(before_start_wrapper, 'epoch')
    qs = qs.annotate(before_start=before_start/3600)

Это тоже не работает;

    qs = Foo.objects.filter(
        bar__baz_id=self.kwargs['baz_pk'],
    )
    start_datetime = F('x__date') + F('x__start')

    before_start_wrapper = ExpressionWrapper(
        F('start') - F(start_datetime), # 'start' is datetime field on Foo, start_datetime is combined F expression
        output_field=DateTimeField()
    )
    before_start = Extract(before_start_wrapper, 'epoch')
    qs = qs.annotate(before_start=before_start/3600)

Джанго делает следующее:

...(EXTRACT('epoch' FROM "foo".came" - ("db_shift"."date" + "db_shift"."start")) AT TIME ZONE) /3600 AS ...

То, что я ожидаю, это:

...(EXTRACT('epoch' FROM "foo".came" - ("db_shift"."date" + "db_shift"."start")AT TIME ZONE)) / 3600 AS ...

Может кто-нибудь предложить решение с Django ORM? Я знаю, что могу выполнить необработанный запрос, но хотел посмотреть, есть ли способ сделать то же самое с Django ORM?

Спасибо.

1 Ответ

0 голосов
/ 19 июня 2019

Я обошел проблему и получил ответ. Требуется только DurationField() в output параметре ExpressionWrapper вместо DateTimeField(). Вот код:

qs = Foo.objects.filter(
    bar__baz_id=self.kwargs['baz_pk'],
)
start_datetime = F('x__date') + F('x__start')

before_start_wrapper = ExpressionWrapper(
    F('start') - F(start_datetime), # 'start' is datetime field on Foo, start_datetime is combined F expression
    output_field=DurationField()
)
before_start = Extract(before_start_wrapper, 'epoch')
qs = qs.annotate(before_start=before_start/3600)

Таким образом, я справился с проблемой, возникшей ранее. Это может быть полезно для кого-то еще.

...