2015-08-28 48 views
4

我正試圖在queryset中的兩個註釋結果之間進行劃分。印象比點擊大得多,所以我應該得到十分數。Django,兩個註釋結果之間的分割將無法正確計算

def get_queryset(self): 
     return googleData.objects.filter(account=self.account_name).\ 
      values('date').\ 
      annotate(Sum('click'), Sum('impression'), Sum('converted_click'), 
        Sum('conversion_value'), Sum('cost'), Sum('conversion_value'), ctr_monthly= Sum('click')/Sum('impression')).\ 
      order_by('-date') 

麻煩這裏:

ctr_monthly= Sum('click')/Sum('impression')) 

在模板中我有:

<td>{{ googleData.ctr_monthly | floatformat:2}} </td> 

,結果是0.00。 如果我做ctr_final = click *印象,它會正確生成。 Click &印象都是整數場。

我試過使用float(),給了我一個語法錯誤。

另一個問題是:建立這樣一個查詢集的最佳實踐是什麼?有什麼辦法可以將它分解成幾段簡短的代碼,並使它更加整潔可讀?

謝謝〜

回答

10

使用Django的新版本,你可以使用新的Func對象Sum前值轉換爲FloatFieldsDecimalFields

​​

即使使用舊版本的Django的,你也許可以ctr_monthly註釋,像這樣之前剛剛指定的Sumoutput_field

from django.db.models import F 
def get_queryset(self): 
    return googleData.objects.filter(
     account=self.account_name 
    ).values('date').annotate(
     click_sum=Sum(
      'click', 
      output_field=FloatField() 
     ), 
     impression_sum=Sum(
      'impression', 
      output_field=FloatField() 
     ), 
     converted_click_sum=Sum('converted_click'), 
     conversion_value_sum=Sum('conversion_value'), 
     cost_sum=Sum('cost') 
    ).annotate(
     ctr_monthly=F('click_sum')/F('impression_sum') 
    ).order_by('-date') 
1

據我所知,沒有辦法做到這一點使用的ORM。

Sum()函數返回與放入它相同的字段類型(即IntegerField()將始終返回一個整數)。您可以使用像ExpressionWrapper這樣的函數來強制輸出爲浮點數,但在這種情況下將不會有所幫助,因爲它已經太遲了:兩個整數的除法將已經返回另一個整數。

要解決您的問題,請從您的查詢中刪除ctr_monthly部分,然後創建一個簡單的模板標記,將兩個數字轉換爲浮點數並將其分開。然後

你的模板將是這樣的: <td>{{ monthly_ctr(googleData.click, googleData.impression) | floatformat:2}} </td>

+0

這工作!謝謝。將所有內容都放在decimalField中是一種更好的做法嗎? – viviwill