如何通过相关对象查询模型并使用 Django ORM 获取查询集中的相关对象

How to query a model by a related object and get the related object in the queryset using the Django ORM

我知道可以使用 Django ORM 使用反向相关字段查询模型。但是是否也可以获取查询匹配的反向相关模型的所有字段?

例如,如果我们有以下模型:

class Location(models.Model):
    name = models.CharField(max_length=50)


class Availability(models.Model):
    location = models.ForeignKey(Location, on_delete=models.CASCADE)

    start_datetime = models.DateTimeField()
    end_datetime = models.DateTimeField()

    price = models.PositiveIntegerField()

是否可以找到在特定时间范围内可用的所有 Location 并在该可用性期间获得 Locationprice?我们假设 Availability 具有相同位置的对象不能有重叠的 start/end 日期时间。

如果 user_start_datetimeuser_end_datetime 是由用户输入的,那么我们可以做类似下面的事情:

Location.objects.filter(
    availability__start_datetime__lte=start_datetime,
    availability__end_datetime__gte=end_datetime)

但我不确定如何同时获取特定 availabilityprice 字段,这确实导致查询匹配。

在原始 SQL 中,我所说的行为可能可以通过这样的方式实现:

SELECT l.id, l.name, a.price
FROM Location l
INNER JOIN Availability a
ON a.location_id = l.id
WHERE /* availability is within user-inputted timeframe */

我考虑过使用 prefetch_related('availability_set') 之类的东西,但这只会给我 所有 与查询匹配的 Location 对象的可用性。我只想要查询时间范围内的 one availability,更具体地说,availability.[=26 的 price =]

当您使用 ORM 时,通常一次从一个模型 class 获取结果。由于 LocationAvailability 是不同的模型,您可以简单地执行以下操作:

availabilities = Availability.objects.filter(
    start_datetime__lte=start_datetime,
    end_datetime__gte=end_datetime)
for availability in availabilities:
    print(availability.location.id, availability.location.name, availability.price)

这是一个易于阅读的实现。

现在,从 Availability 对象(在 availability.location 中)访问 Location 需要第二个 SQL 查询。您可以使用 select_related:

对其进行优化

This is a performance booster which results in a single more complex query but means later use of foreign-key relationships won’t require database queries.

只需将其附加到您的原始查询,即:

availabilities = Availability.objects.select_related('location').filter(...

这将在后台创建一个 SQL 连接语句并且 Location 对象不需要额外的查询。