我正在写一个功能,需要一个项目的平均价格在不同的时间(周,月,季度等)。这是模型:
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天的月份不会削减它我害怕,谢谢你的建议!
解决方案是两部分,首先使用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}
值得注意的是,您可以通过更改month
param来更改.aggregate()
字典的键。
dateutil
的relativedelta可以处理数天,数周,数年甚至更多。一个很好的包,我将重写我的本土hax。
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'))
我会选择360-day calendar而不用担心这些小小的不准确之处。只需使用过去30天的“上个月平均值”和过去90天的“上一季度平均值”。
首先,您对过去7天或上周感兴趣吗?如果答案是上周,则查询不正确。
如果超过您关注的“n”天,那么您的查询是正确的,我想您可以放松并使用30天一个月和90天一季度。