Django/python 按月和季度聚合日期
ItemPrice.objects.filter(item__id = 1)
.filter(date_lt = TODAY)
.filter(date_gte = TODAY_MINUS_7_DAYS)
.filter(date_.aggregate(Avg('value'))
我正在写一个功能,需要计算一个商品在不同时间段内的平均价格(比如一周、一个月、一个季度等)。这是我的模型:
class ItemPrice(models.Model):
item = models.ForeignKey(Item)
date = models.DateField()
price = models.FloatField()
这个模型会记录商品随时间变化的价格,新商品会在频繁但不规律的时间点被添加进来。
计算过去一周的平均价格
其实很简单,因为一周总是有7天。但是一个月和一个季度呢?它们的天数是不一样的……?
谢谢!
补充说明:这个应用是为一个金融机构开发的,30天的月份不太适用,感谢你的建议!
4 个回答
1
首先,你是想知道过去7天的情况,还是想了解上个星期的情况?如果你想要的是上个星期,那你的查询就不对了。
如果你关心的是过去的“n”天,那么你的查询就是正确的。我想你可以放轻松,直接用30天代表一个月,用90天代表一个季度就可以了。
2
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'))
这里的内容是一个链接,指向StackOverflow网站上的一个问题解答。这个链接的标题是“从那里得到的灵感”。
2
这个解决方案分为两部分,第一部分是使用django ORM的聚合函数,第二部分是使用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()
的参数来更改month
字典的键。
dateutil
中的relativedelta可以处理天、周、年等等,非常好用的库,我会重新编写我自己写的那些小工具。