我正在尝试创建一个完整的查询集,现在我所需要的只是从我的模型中获取两个DateTime
字段之间的月份,可以在单个查询集中执行此操作。我不是在谈论过滤器,因为在模型中例如我有两个datetimeField()
,现在我想做的是,在这个日期之间得到几个月。
如果你的数据库支持DurationField
你可以使用 ExtractMonth:
from django.db import models
from django.db.models.functions import ExtractMonth
queryset = MyModel.objects.annotate(
diff=models.ExpressionWrapper(
models.F('date1') - models.F('date2'), output_field=models.DurationField())
).annotate(months=ExtractMonth('diff'))
给定的答案对我在 postgres 上不起作用,因为diff
字段(持续时间字段(仅支持Extract
天功能。 ExtractMonth
返回"0"。
这是我找到的解决方案:
queryset = MyModel.objects.annotate(
months=(ExtractYear("date2") - ExtractYear("date1")) * 12 + (ExtractMonth("date2") - ExtractMonth("date1"))
)
请注意,它只考虑每个月第一天之间的差异,而不是按天数给出的最终小数部分。在此解决方案中,2020-08-12 被视为与 2020-08-01 相同。
Django v4.0.4
PostgreSQL v13.4
date2_date1_months_elapsed
返回两个日期之间经过了多少个月(以整数形式(。
created_on_months_elapsed
返回从今天到创建日期之间经过了多少个月(整数(。
from django.db.models import F, IntegerField
from django.db.models.functions import Cast, ExtractDay, TruncDate
from django.utils import timezone
class MyModel(models.Model):
date1 = models.DateTimeField()
date2 = models.DateTimeField()
created_on = models.DateTimeField(default=timezone.now)
...
queryset = MyModel.objects.annotate(
date2_date1_days_diff=Cast(
ExtractDay(
TruncDate(F("date2")) - TruncDate(F("date1"))
),
IntegerField(),
),
date2_date1_months_elapsed=Cast(
F("date2_date1_days_diff") / (365 / 12), IntegerField()
),
created_on_days_diff=Cast(
ExtractDay(
TruncDate(timezone.now()) - TruncDate(F("created_on"))
),
IntegerField(),
),
created_on_months_elapsed=Cast(
F("created_on_days_diff") / (365 / 12), IntegerField()
)
)