def test_expressions(self): self.assertEqual( repr(Case(When(a=1))), "<Case: CASE WHEN <Q: (AND: ('a', 1))> THEN Value(None), ELSE Value(None)>" ) self.assertEqual(repr(Col('alias', 'field')), "Col(alias, field)") self.assertEqual(repr(Date('published', 'exact')), "Date(published, exact)") self.assertEqual(repr(DateTime('published', 'exact', utc)), "DateTime(published, exact, %s)" % utc) self.assertEqual(repr(F('published')), "F(published)") self.assertEqual(repr(F('cost') + F('tax')), "<CombinedExpression: F(cost) + F(tax)>") self.assertEqual( repr(ExpressionWrapper( F('cost') + F('tax'), models.IntegerField())), "ExpressionWrapper(F(cost) + F(tax))") self.assertEqual(repr(Func('published', function='TO_CHAR')), "Func(F(published), function=TO_CHAR)") self.assertEqual(repr(OrderBy(Value(1))), 'OrderBy(Value(1), descending=False)') self.assertEqual(repr(Random()), "Random()") self.assertEqual(repr(RawSQL('table.col', [])), "RawSQL(table.col, [])") self.assertEqual(repr(Ref('sum_cost', Sum('cost'))), "Ref(sum_cost, Sum(F(cost)))") self.assertEqual(repr(Value(1)), "Value(1)")
def _get_select(self, col, lookup_type): return Date(col, lookup_type)
def time_series(qs, date_field, aggregate, interval, date_from=None, date_to=None): current_timezone = timezone.get_current_timezone() is_date = interval in DATE_SERIES if isinstance(qs.model._meta.get_field(date_field), models.DateTimeField): db_interval = DateTime(date_field, interval, current_timezone) else: db_interval = Date(date_field, interval) if not isinstance(aggregate, dict): aggregate = {'aggregate': aggregate} SeriesRecord = namedtuple('SeriesRecord', ['time_value'] + aggregate.keys()) if is_date: if date_from and not isinstance(date_from, datetime): date_from = current_timezone.localize( datetime.combine(date_from, time.min)) if date_to and not isinstance(date_to, datetime): date_to = current_timezone.localize( datetime.combine(date_to, time.max)) if date_from is not None: qs = qs.filter(**{date_field + '__gte': date_from}) if date_to is not None: qs = qs.filter(**{date_field + '__lte': date_to}) qs = (qs.annotate(time_value=db_interval).values_list( 'time_value').order_by('time_value').annotate(**aggregate)) def convert_date(val): if is_date and isinstance(val, datetime): return val.date() return val records = [SeriesRecord(convert_date(val[0]), *val[1:]) for val in qs] if len(records): date_from = date_from or records[0].time_value date_to = date_to or records[-1].time_value empty_record = partial(SeriesRecord, **{k: None for k in aggregate.keys()}) return fill_time_series_gap(records, empty_record, interval, date_from, date_to) # example: # # time_series( # User.objects.all(), # date_field='date_joined', # aggregate={'count': Count('id')}, # interval='day', # date_to=timezone.localtime(timezone.now()).date() # ) # # [SeriesRecord(time_value=datetime.date(2015, 9, 17), count=10), # SeriesRecord(time_value=datetime.date(2015, 9, 18), count=None), # SeriesRecord(time_value=datetime.date(2015, 9, 19), count=None), # ...