繁体   English   中英

Django ORM:两个日期之间的天数差异

[英]Django ORM: timedelta difference in days between 2 dates

在此处输入图片说明

我有一个数据库表,表示与给定产品相关的费用。

考虑到这些费用是每天的,它们有一个from_date (它们开始的日期)和to_date (它们结束的日期)。 to_date可以为空,因为这些费用可能仍在继续。

给定 2 个 Python datetime s、 start_dateend_date ,我需要在 ORM 中生成my_product期间的总花费。

>>> start_date
datetime.datetime(2021, 8, 20, 0, 0)

>>> end_date
datetime.datetime(2021, 9, 21, 0, 0)

在这种情况下,预期的输出应该是:

(-104 * (days between 08/20 and 08/25)) + (-113 * (days between 08/26 and 09/21)

这是我到目前为止所得到的:

(
my_product.income_streams
    .values("product")
    .filter(type=IncomeStream.Types.DAILY_EXPENSE)
    .filter(add_to_commission_basis=True)
    .annotate(period_expenses=Case(
        When(Q(from_date__lte=start_date) & Q(to_date__lte=end_date),
 then=ExpressionWrapper( start_date - F('to_date'), output_field=IntegerField()))
    ), # Other When cases...
)
) # Sum all period_expenses results and you've got the solution

这就是给我带来问题的原因:

then=ExpressionWrapper( start_date - F('to_date'), output_field=IntegerField())

这个表达式总是返回 0(请注意,这就是为什么我什至不尝试乘以value :那将是下一步)。

显然start_date - F('to_date')与“给我这两个日期之间的天数差异”不同。

您可以在 Python 中使用timedeltatimedelta ORM 中的等价物是什么?

我试过ExtractDay

then=ExpressionWrapper( ExtractDay(start_date - F('to_date'))

但我得到: django.db.utils.OperationalError: user-defined function raised exception

并且还尝试了DurationField

then=ExpressionWrapper(start_date - F('to_date'), output_field=DurationField())

但这也返回零: datetime.timedelta(0)

将 start_date 转换为 DateTimeField 解决了问题,下一步将差异转换为 DurationField。

所以:

Cast(Cast(start_date, output_field=DateTimeField()) - F('to_date'), output_field=DurationField())

这在任何数据库后端都可以正常工作,但为了获得天数差异,您需要将其包装在 ExtractDay 中,这将引发ValueError: Extract requires native DurationField database support. 如果您使用 SQLite。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM