我正在尝试在django聚合查询中使用模型方法。我不确定是否可能,我可能会以错误的方式去做。
这是我想要查询的模型。
class ClassNumbers(models.Model):
"""
The class year level and number inline model for a booking
"""
booking = models.ForeignKey('Booking')
yearLevel = models.CharField(max_length=10, choices=YEAR_CHOICES, verbose_name='Year Level')
numberOfStudents = models.IntegerField(verbose_name='Number of Students')
class Booking(models.Model):
# A shorter version of the model
date = models.DateField()
institution = models.ForeignKey(Institution)
def getStudentTotal(self):
# Total class numbers
classes = ClassNumbers.objects.filter(booking=self.id)
classTotal = 0
if ( classes ):
for c in classes:
classTotal += c.numberOfStudents
return classTotal
def getHDSV(self):
HDSVunits = {
'Full-Day': 2.0,
'Half-Day AM': 1.0,
'Half-Day PM': 1.0,
'Three-Quarter Day': 1.5,
'1 Hour': 0.5,
'Custom': 1.0,
}
numStudents = self.getStudentTotal()
result = numStudents * HDSVunits[self.price.name]
return result
getHDSV
方法返回应用程序所在内部使用的报告指标。我希望将指标汇总为日期之间的月份总数。
我不是aggregate
/ annotate
主人。到目前为止,我的尝试并未取得我所追求的结果。
最终,我在指定日期之间查询Bookings
,然后循环结果,并通过每次迭代调用getHDSV
方法将报告单位计入字典。当然,生成的字典没有按照我想要的方式排序。
所以我现在转而寻求帮助。
考虑到生成度量标准的方式,我可以在查询中聚合数据时调用模型方法吗?或者我应该在创建HDSVunits
时使用aggregate
字典?或者有更好的方法吗?
感谢。
答案 0 :(得分:2)
您的设置非常困难,可能更容易在HDSVunits
模型上使用Price
映射,以便在查询中更轻松地进行访问。
我能想到的最好的是:
Booking.objects.aggregate(
hdsv=(
Sum('classnumbers__numberofstudents') *
Case(
When(price__name='Full-Day', then=2.0),
When(price__name='Half-Day AM', then=1.0),
When(price__name='Full-Day PM', then=1.0),
When(price__name='Three-Quarter Day', then=1.5),
When(price__name='1 Hour', then=0.5),
When(price__name='Custom', then=1.0),
output_field=FloatField(),
)
)
)
如果HDSV值存储为Price
模型上的字段,您可以执行以下操作:
Booking.objects.aggregate(
hdsv=Sum('classnumbers__numberofstudents') * F('price__hdsv'))
另外,您应该考虑遵循Python naming convensions,这将使其他Python开发人员更容易为您提供帮助。
答案 1 :(得分:0)
如果getHDSV
返回的数据不是来自数据库,那么aggregate
和annotate
将无法用于收集统计数据。