How to Combine Date and Time Fields into DateTime Field in Django F Expression

孤街浪徒 提交于 2019-12-11 07:27:51

问题


I have to get the difference of two datetime fields but one is pure datetime field and other is a combination of date and time. I tried this one:

    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)

This also doesn't work;

    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)

What django does is as follows:

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

What I am expecting is:

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

Can some one please provide the solution with Django ORM? I know I can run a raw query but wanted to look if there is a way to do the same with Django ORM?

Thanks.


回答1:


I have worked around the issue and got the answer. Only need the DurationField() in the output param of the ExpressionWrapper instead of DateTimeField(). Here is the code:

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)

This way I got to manage the issue I had earlier. This might be helpful for someone else.



来源:https://stackoverflow.com/questions/56631679/how-to-combine-date-and-time-fields-into-datetime-field-in-django-f-expression

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!