2011-09-11 39 views
7

我想在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方法將報告單元彙總到字典中。當然,結果字典並不按我想要的方式排序。 所以我現在轉向尋求幫助。

鑑於生成度量的方式,我可以在查詢中彙總數據時調用模型方法嗎?或者,我應該在創建aggregate時使用HDSVunits字典?或者,還有更好的方法?

謝謝。

回答

0

如果getHDSV返回的數據不是來自數據庫,那麼aggregateannotate將無法​​用於收集它的統計信息。

1

你有一個相當困難的設置,HDSVunits模型上的HDSVunits映射可能更容易使查詢更容易訪問。

我能想出的最好的是這樣的:

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開發人員更容易幫助你。