我正在尝试在Django中编写嵌套查询。在SQL中这很简单,但是对于Django,我在确定我是否做得对时遇到了一些麻烦。我有三个型号。 Area
,Location
和Measurement
。
区域
class Area(models.Model):
name = models.CharField(max_length=200)
longitude = models.FloatField()
latitude = models.FloatField()
位置
class Location(models.Model):
name = models.CharField(max_length=200)
altitude = models.IntegerField()
area = models.ForeignKey(Area, on_delete=models.CASCADE)
测量
class Measurement(models.Model):
value = models.FloatField()
date = models.DateTimeField()
location = models.ForeignKey(Location, on_delete=models.CASCADE)
在Area
内,我需要一个函数来返回该区域的平均测量值。基本上,我需要对该区域的所有位置进行平均测量。 Area
可以有多个位置,但位置可以有一个区域。在Area
模型中,我实现了这个功能:
def average_measurement(self):
all_locations = self.location_set.all()
return all_locations.measurement_set.all().aggregate(Avg('value'))
这相当于在Django中编写嵌套查询。我首先得到所有位置,然后找到他们所有测量的平均值。我这样做了吗?
关于一个问题,这个查询是否等同于这样做:
avg = 0
locations = self.location_set.all()
sum = 0
counter = 0
for l in locations: measurement = l.measurement_set.all()
if measurement:
for m in measurement:
sum += m.value
counter += 1
if counter != 0:
avg = sum / counter
return avg
答案 0 :(得分:2)
使用对象列表时,通常可以直接查询给定模型。所以你可以改用:
def average_measurement(self):
return Measurement.objects.filter(location__area = self).aggregate(Avg('value'))['value__avg']
您也可以在第二个例子中采用这种方法:
avg = 0
sum = 0
counter = 0
for m in Measurement.objects.filter(location__area = self):
sum += m.value
counter += 1
if counter != 0:
avg = sum / counter
return avg