【发布时间】:2021-01-18 21:34:03
【问题描述】:
我提出了我的问题的简化版本。我有场地和时间段以及用户和预订,如下面的模型描述所示。时间段对所有场地通用,用户可以在场地预订一个时间段,直到达到场地容量。
class Venue(models.Model):
name = models.Charfield(max_length=200)
capacity = models.PositiveIntegerField(default=0)
class TimeSlot(models.Model):
start_time = models.TimeField()
end_time = models.TimeField()
class Booking(models.Model):
user = models.ForeignKey(User)
time_slot = models.ForeignKey(TimeSlot)
venue = models.ForeignKey(Venue)
现在我想尽可能高效地获取场地和时间段的所有可能组合,并注释每个组合的预订计数,包括预订数量为 0 的情况。
我已经设法在原始 SQL 中使用 Venue 和 TimeSlot 表上的交叉连接来实现这一点。大意如下。然而,尽管进行了详尽的搜索,但仍未找到 django 等价物。
SELECT venue.name, timeslot.start_time, timeslot.end_time, count(booking.id)
FROM myapp_venue as venue
CROSS JOIN myapp_timeslot as timeslot
LEFT JOIN myapp_booking as booking on booking.time_slot_id = timeslot.id
GROUP BY venue.name, timeslot.start_time, timeslot.end_time
我还可以对查询进行注释,以检索该组合的预订确实存在的预订计数。但那些预订量为 0 的组合被排除在外。示例:
qs = Booking.objects.all().values(
venue=F('venue__name'),
start_time=F('time_slot__start_time'),
end_time=F('time_slot__end_time')
).annotate(bookings=Count('id')) \
.order_by('venue', 'start_time', 'end_time')
如何使用django ORM实现CROSS JOIN查询的效果?
【问题讨论】:
标签: python django join orm annotations