Django:按日期过滤相关字段会产生不需要的结果
Django: Filtering a related field by date yields unwanted results
型号:
class Vehicle(models.Model):
licence_plate = models.CharField(max_length=16)
class WorkTime(models.Model):
work_start = models.DateTimeField()
work_end = models.DateTimeField()
vehicle = models.ForeignKey(Vehicle, on_delete=models.SET_NULL, related_name="work_times")
然而,当我尝试使用以下方法过滤这些工作时间时:
qs = Vehicle.objects.filter(
work_times__work_start__date__gte="YYYY-MM-DD",
work_times__work_end__date__lte="YYYY-MM-DD").distinct()
我得到的结果不符合给定的时间范围。最常见的是,当 work_end 适合某物时,它 returns 来自 WorkTime
的一切
我想要的:
for vehicle in qs:
for work_time in vehicle.work_times:
print(vehicle, work_time.work_start, work_time.work_end)
过滤器对 Vehicle
中的 .work_times
没有影响,它只会确保 qs
中的 Vehicle
包含 在给定范围内至少一个WorkTime
。
您可以使用 Prefetch
object [Django-doc] 以允许对相关经理进行有效过滤:
from django.db.models import Prefetch
qs = Vehicle.objects.prefetch_related(
<b>Prefetch(</b>
'work_times',
WorkTime.objects.filter(
work_start__date__range=('2021-03-01', '2021-03-12')
),
to_attr='filtered_work_times'
<b>)</b>
)
然后您可以使用:
for vehicle in qs:
for work_time in vehicle<b>.filtered_work_times</b>:
print(vehicle, work_time.work_start, work_time.work_end)
型号:
class Vehicle(models.Model):
licence_plate = models.CharField(max_length=16)
class WorkTime(models.Model):
work_start = models.DateTimeField()
work_end = models.DateTimeField()
vehicle = models.ForeignKey(Vehicle, on_delete=models.SET_NULL, related_name="work_times")
然而,当我尝试使用以下方法过滤这些工作时间时:
qs = Vehicle.objects.filter(
work_times__work_start__date__gte="YYYY-MM-DD",
work_times__work_end__date__lte="YYYY-MM-DD").distinct()
我得到的结果不符合给定的时间范围。最常见的是,当 work_end 适合某物时,它 returns 来自 WorkTime
的一切我想要的:
for vehicle in qs:
for work_time in vehicle.work_times:
print(vehicle, work_time.work_start, work_time.work_end)
过滤器对 Vehicle
中的 .work_times
没有影响,它只会确保 qs
中的 Vehicle
包含 在给定范围内至少一个WorkTime
。
您可以使用 Prefetch
object [Django-doc] 以允许对相关经理进行有效过滤:
from django.db.models import Prefetch
qs = Vehicle.objects.prefetch_related(
<b>Prefetch(</b>
'work_times',
WorkTime.objects.filter(
work_start__date__range=('2021-03-01', '2021-03-12')
),
to_attr='filtered_work_times'
<b>)</b>
)
然后您可以使用:
for vehicle in qs:
for work_time in vehicle<b>.filtered_work_times</b>:
print(vehicle, work_time.work_start, work_time.work_end)