2011-02-01 145 views
1

我正在寫一個功能集合,需要在不同的時間(周,月,季度等),這裏的項目平均價格的模型:Django的/ Python的日期按月和季度

class ItemPrice(models.Model): 
    item = models.ForeignKey(Item) 
    date = models.DateField() 
    price = models.FloatField() 

這模型跟蹤項目的價格隨着時間的推移,新項目以頻繁但不固定的時間間隔添加。 過去一週求出平均price是很容易的:

ItemPrice.objects.filter(item__id = 1) 
    .filter(date_lt = TODAY) 
    .filter(date_gte = TODAY_MINUS_7_DAYS) 
    .filter(date_.aggregate(Avg('value')) 

一個星期總有7天,但對於月和季度?他們有不同的天數......?

謝謝!

編輯: 該應用程序是爲一個金融組織,30天的月份不會削減它恐怕,謝謝你的建議!

回答

2

該解決方案是兩部分,首先使用django ORM的aggregation函數,第二部分使用python-dateutil

from dateutil.relativedelta import relativedelta 

A_MONTH = relativedelta(months=1) 

month = ItemPrice.objects \ 
    .filter(date__gte = date - A_MONTH) \ 
    .filter(date__lt = date) \ 
    .aggregate(month_average = Avg('price')) 

month等於:

{'month_average': 40} 

這是值得注意的是,你可以通過改變.aggregate() PARAM改變month字典的關鍵。

dateutil的relativedelta可以處理日,周,年和更多。一個很好的包裹,我會重寫我的家鄉hax。

1

我會去爲360-day calendar而不是擔心這些小的不準確。只需使用過去30天的「上個月平均水平」和過去90天的「上一季度平均水平」即可。

+0

金融趨勢的應用程序,我懷疑偏差是不可接受的! – 0atman 2011-02-01 13:29:07

+0

你真的看了我鏈接到的維基百科文章嗎? 360天的日曆是爲了這個目的而設計的。畢竟,爲什麼要顯示平均值「過去一個月」的應用程序在1月31日(平均過去31天)和2月1日(平均過去28天)有不同的表現? – 2011-02-01 13:32:28

1

首先,你對過去7天還是最後一週感興趣?如果答案是最後一週,你的查詢是不正確的。

如果過去「n」天涉及到你,那麼你的查詢是正確的,我想你可以放鬆並使用30天一個月和90天一個季度。

1
import datetime 
from dateutil import relativedelta, rrule 

obj = self.get_object() 
datenow = datetime.datetime.now() 

quarters = rrule.rrule(
     rrule.MONTHLY, 
     bymonth=(1, 4, 7, 10), 
     bysetpos=-1, 
     dtstart=datetime.datetime(datenow.year, 1, 1), 
     count=5) 

    first_day = quarters.before(datenow) 
    last_day = (quarters.after(datenow) - relativedelta.relativedelta(days=1)) 

    quarter = Payment.objects.filter(
     operation__department__cashbox__id=obj.pk, 
     created__range=(first_day, last_day)).aggregate(count=Sum('amount')) 

inspiration from there

相關問題