过滤具有相同日期时间字段的查询集

问题描述 投票:0回答:2

我正在尝试过滤具有相同 DateTime 字段的查询集:

objects = Obj.objects.filter(start_date_time=F('end_date_time'))
objects
<QuerySet []>

模型.py:

start_date_time = models.DateTimeField(default=now, blank=True)
end_date_time = models.DateTimeField(default=now, blank=True)

如果我删除微秒,则字段相等:

obj = Obj.objects.filter(id='id').first()
obj.start_date_time
datetime.datetime(2023, 3, 10, 9, 24, 29, 326238, tzinfo=<UTC>)
obj.end_date_time
datetime.datetime(2023, 3, 10, 9, 24, 29, 326241, tzinfo=<UTC>)
obj.start_date_time == obj.end_date_time
False
obj.start_date_time.replace(microsecond=0) == obj.end_date_time.replace(microsecond=0)
True

如何正确的向数据库发起请求?

python django datetime django-queryset
2个回答
2
投票

你可以使用

Trunc
函数来截断毫秒信息并像这样过滤:

objects = Obj.objects.annotate(truc_start_date_time=Trunc('start_datetime', 'second', output_field=DateTimeField()), trunc_end_date_time==Trunc('endt_datetime', 'second', output_field=DateTimeField())).filter(trunc_start_date=F('trunc_end_date'))

另一种选择是使用日期时间对象的所有段进行过滤(即datehourminutesecond

objects = Obj.objects.filter(start_date_time_day__date = F('end_datetime__date'), start_date_time_day__hour =  F('end_datetime__hour'), start_date_time_day__minute =  F('end_datetime__minute'), start_date_time_day__second =  F('end_datetime__second'))

1
投票

一种稍微更有效的方法是使用

.alias(…)
[Django-doc] 截断,然后直接过滤,这将防止值最终出现在
SELECT
子句中。我们也可以使用
TruncSecond
[Django-doc]

from django.db.models.functions import TruncSecond

Obj.objects.alias(trunc_start_date_time=TruncSecond('start_date_time')).filter(
    trunc_start_date_time=TruncSecond('end_date_time')
)
© www.soinside.com 2019 - 2024. All rights reserved.