我正在尝试过滤具有相同 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
如何正确的向数据库发起请求?
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'))
另一种选择是使用日期时间对象的所有段进行过滤(即date,hour,minute,second)
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'))
.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')
)