如何通过相关对象查询模型并使用 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
并在该可用性期间获得 Location
的 price
?我们假设 Availability
具有相同位置的对象不能有重叠的 start/end 日期时间。
如果 user_start_datetime
和 user_end_datetime
是由用户输入的,那么我们可以做类似下面的事情:
Location.objects.filter(
availability__start_datetime__lte=start_datetime,
availability__end_datetime__gte=end_datetime)
但我不确定如何同时获取特定 availability
的 price
字段,这确实导致查询匹配。
在原始 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 获取结果。由于 Location
和 Availability
是不同的模型,您可以简单地执行以下操作:
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
对象不需要额外的查询。
我知道可以使用 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
并在该可用性期间获得 Location
的 price
?我们假设 Availability
具有相同位置的对象不能有重叠的 start/end 日期时间。
如果 user_start_datetime
和 user_end_datetime
是由用户输入的,那么我们可以做类似下面的事情:
Location.objects.filter(
availability__start_datetime__lte=start_datetime,
availability__end_datetime__gte=end_datetime)
但我不确定如何同时获取特定 availability
的 price
字段,这确实导致查询匹配。
在原始 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 获取结果。由于 Location
和 Availability
是不同的模型,您可以简单地执行以下操作:
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
对象不需要额外的查询。