Django/python date aggregation by month and quarter
Question: I'm writing a feature that requires the average price of an item over
different times (week, month, quarter etc.) Here's the model:

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

This model tracks the price of the item over time, with new Items being added
at frequent, but not regular, intervals. Finding the average `price` over the
last week is easy enough:

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

As a week always has 7 days, but what about month and quarter? They have
different numbers of days...?

Thanks!

EDIT: The app is for a finance org, 30-day months wont cut it I'm afraid,
thanks for the suggestion!


Answer: The solution is two-part, first using the
[aggregation](http://docs.djangoproject.com/en/dev/topics/db/aggregation/)
functions of django ORM, the second using
[datutil](http://niemeyer.net/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` equals:

    
    
    {'month_average': 40}
    

It's worth noticing that you can change the key of the `month` dictionary by
changing the `.aggregate()` param.

`dateutil`'s relativedelta can handle days, weeks, years and lots more. An
excellent package, I'll be re-writing my home-grown hax.

