Skip to content

Commit

Permalink
Added the ability to set the default aggregate when instantiating Que…
Browse files Browse the repository at this point in the history
…rySetStats. Added setting QUERYSETSTATUS_DEFAULT_AGGREGATE to affect default aggregate and moved sane default of Count to this configuration.
  • Loading branch information
mcroydon committed Mar 28, 2010
1 parent 5fb5d94 commit 1b64065
Showing 1 changed file with 15 additions and 8 deletions.
23 changes: 15 additions & 8 deletions qsstats.py
@@ -1,20 +1,22 @@
from dateutil.relativedelta import relativedelta
from django.conf import settings
from django.db.models import Count
import datetime

class QuerySetStats(object):
"""
Generates statistics for a queryset.
"""
def __init__(self, qs, date_field=None):
def __init__(self, qs, date_field=None, aggregate=None):
self.qs = qs
self.date_field = date_field
self.aggregate = aggregate or getattr(settings, 'QUERYSETSTATUS_DEFAULT_AGGREGATE', Count)
# MC_TODO: Danger in caching this?
self.update_today()

# MC_TODO: investigate dynamic dispatch?
# Aggregates for a specific period of time

def for_day(self, dt, date_field=None, aggregate=Count):
def for_day(self, dt, date_field=None, aggregate=self.aggregate):
date_field = date_field or self.date_field
kwargs = {
'%s__year' % date_field : dt.year,
Expand All @@ -24,30 +26,35 @@ def for_day(self, dt, date_field=None, aggregate=Count):
agg = self.qs.filter(**kwargs).aggregate(agg=aggregate('id'))
return agg['agg']

def this_day(self, date_field=None, aggregate=Count):
def this_day(self, date_field=None, aggregate=self.aggregate):
date_field = date_field or self.date_field
return self.for_day(self.today, date_field, aggregate)

def for_month(self, dt, date_field=None, aggregate=Count):
def for_month(self, dt, date_field=None, aggregate=self.aggregate):
date_field = date_field or self.date_field

first_day = datetime.date(year=dt.year, month=dt.month, day=1)
last_day = first_day + relativedelta(day=31)
return self.get_aggregate(first_day, last_day, date_field, aggregate)

def this_month(self, date_field=None, aggregate=Count):
def this_month(self, date_field=None, aggregate=self.aggregate):
return self.for_month(self.today, date_field, aggregate)

def for_year(self, dt, date_field=None, aggregate=Count):
def for_year(self, dt, date_field=None, aggregate=self.aggregate):
date_field = date_field or self.date_field

first_day = datetime.date(year=dt.year, month=1, day=1)
last_day = datetime.date(year=dt.year, month=12, day=31)
return self.get_aggregate(first_day, last_day, date_field, aggregate)

def this_year(self, date_field=None, aggregate=Count):
def this_year(self, date_field=None, aggregate=self.aggregate):
return self.for_year(self.today, date_field, aggregate)

# Aggregate over time intervals

def time_series(self, start_time, end_time, interval='days', date_field=None, aggregate=self.aggregate):
pass

# Utility functions
def update_today(self):
self.today = datetime.date.today()
Expand Down

0 comments on commit 1b64065

Please sign in to comment.