英文:
Use objects from one django model to filter objects from another django objects
问题
我正在进行我的研究项目。我有2个模型:
class RoutePoint(geo_models.Model):
vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE, null=False, blank=False,
related_name='routepoints')
point = geo_models.PointField()
datetime = models.DateTimeField()
class Travel(models.Model):
vehicle = models.ForeignKey(Vehicle, on_delete=models.DO_NOTHING, null=False, blank=False,
related_name='travels')
begin = models.DateTimeField()
end = models.DateTimeField()
第一个模型包含了车辆的地理坐标点以及车辆到达那里的日期和时间信息。第二个模型包含了车辆行程的开始和结束时间。
我有一些带有两个字段的Curl请求 - start_date
和end_date
,让我们称其为报告的某种请求。
所以,首先我需要获取类似这样的数据:
SELECT vehicle_id, begin, end
FROM park_travel
WHERE begin > "2022-12-30" AND end < "2023-01-06"
我将其称为result
。
然后,我需要获取类似以下的数据:
SELECT vehicle_id, point, datetime
FROM park_routepoint
WHERE vehicle_id = result.vehicle_id
AND datetime > result.begin
AND datetime < result.end
而且,我需要在不使用原始SQL的情况下完成这个任务...
英文:
I'm doing my studying project. I have 2 models:
class RoutePoint(geo_models.Model):
vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE, null=False, blank=False,
related_name='routepoints')
point = geo_models.PointField()
datetime = models.DateTimeField()
class Travel(models.Model):
vehicle = models.ForeignKey(Vehicle, on_delete=models.DO_NOTHING, null=False, blank=False,
related_name='travels')
begin = models.DateTimeField()
end = models.DateTimeField()
First one contains geopoints for vehicle and date and time for vehicle getting there.
Second one countains the begining and the ending of the rides for vehicles.
I'm having some curl request with two fields - start_date
and end_date
, let's call it some kind request for report.
So, at first I need to get something like this:
SELECT vehicle_id, begin, end
FROM park_travel
WHERE begin > "2022-12-30" AND end < "2023-01-06"
I'll call it result
.
And after that i need to get something like:
SELECT vehicle_id, point, datetime
FROM park_routepoint
WHERE vehicle_id = result.vehicle_id
AND datetime > result.begin
AND datetime < result.end
And I have to do it without raw sql...
答案1
得分: 1
from django.db.models import F
route_points = RoutePoint.objects.filter(
vehicle__travel__begin__lt=F("datetime"),
vehicle__travel__end__gt=F("datetime")
)
然后简单地迭代route_points
查询集:
for route_point in route_points:
print(route_point.vehicle, route_point.point, route_point.datetime)
英文:
You can do this in one query using double underscore notation and F
expressions:
from django.db.models import F
route_points = RoutePoint.objects.filter(
vehicle__travel__begin__lt=F("datetime"),
vehicle__travel__end__gt=F("datetime")
)
then simply iterate over the route_points
queryset:
for route_point in route_points:
print(route_point.vehicle, route_point.point, route_point.datetime)
答案2
得分: 0
你可以筛选Travel的Queryset:
start_date = '2022-12-30'
end_date = '2023-01-06'
travel_qs = Travel.objects.filter(begin__gt=start_date,
end__lt=end_date).values('vehicle_id', 'begin', 'end')
现在你可以使用travel_qs
来检索RoutePoint的点:
route_point_qs = RoutePoint.objects.filter(vehicle_id__in=travel_qs.values('vehicle_id'),
datetime__gt=travel_qs.values('begin'),
datetime__lt=travel_qs.values('end')).values('vehicle_id', 'point', 'datetime')
英文:
You can filter the Travel Queryset:
start_date = '2022-12-30'
end_date = '2023-01-06'
travel_qs = Travel.objects.filter(begin__gt=start_date,
end__lt=end_date).values('vehicle_id', 'begin', 'end')
Now you can use travel_qs
to retrieve the Points from RoutePoint:
route_point_qs = RoutePoint.objects.filter(vehicle_id__in=travel_qs.values('vehicle_id'),
datetime__gt=travel_qs.values('begin'),
datetime__lt=travel_qs.values('end')).values('vehicle_id', 'point', 'datetime')
答案3
得分: 0
我是这样做的:
vehicles_with_dates = travels.values('vehicle_id').annotate(min_dt=Min('begin'), max_dt=Max('end'))
route_points = RoutePoint.objects.filter(
vehicle_id__in=vehicles_with_dates.values('vehicle_id'),
datetime__gt=vehicles_with_dates.values('min_dt'),
datetime__lt=vehicles_with_dates.values('max_dt')
)
它完全正常工作,感谢Iqbal Hussain。
英文:
I did it like this:
vehicles_with_dates = travels.values('vehicle_id').annotate(min_dt=Min('begin'), max_dt=Max('end'))
route_points = RoutePoint.objects.filter(
vehicle_id__in=vehicles_with_dates.values('vehicle_id'),
datetime__gt=vehicles_with_dates.values('min_dt'),
datetime__lt=vehicles_with_dates.values('max_dt')
)
It worked perfectly fine, thanks to Iqbal Hussain.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论