Skip to content

Commit

Permalink
fix compatibility with older Django versions, fix date, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
PetrDlouhy committed Feb 4, 2020
1 parent d36ed1c commit 21a13ed
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 12 deletions.
26 changes: 14 additions & 12 deletions admin_tools_stats/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
import logging
from collections import OrderedDict
from datetime import timedelta
from datetime import date, datetime, timedelta

from cache_utils.decorators import cached

Expand Down Expand Up @@ -375,21 +375,21 @@ def get_time_series(self, dynamic_criteria, all_criteria, request, time_since, t
self.operation_field_name = 'id'

operation = {
'AvgCountPerInstance': ExpressionWrapper(
'AvgCountPerInstance': lambda field_name, distinct, dkwargs: ExpressionWrapper(
1.0 *
Count(self.operation_field_name, distinct=self.distinct, filter=dkwargs) /
Count('id', distinct=True, filter=Q(**{self.operation_field_name + "__isnull": False})),
Count(field_name, distinct=distinct, filter=dkwargs) /
Count('id', distinct=True, filter=Q(**{field_name + "__isnull": False})),
output_field=models.FloatField()
),
'Count': Count(self.operation_field_name, distinct=self.distinct, filter=dkwargs),
'Sum': Sum(self.operation_field_name, distinct=self.distinct, filter=dkwargs),
'Avg': Avg(self.operation_field_name, distinct=self.distinct, filter=dkwargs),
'StdDev': StdDev(self.operation_field_name, filter=dkwargs),
'Max': Max(self.operation_field_name, filter=dkwargs),
'Min': Min(self.operation_field_name, filter=dkwargs),
'Variance': Variance(self.operation_field_name, filter=dkwargs),
'Count': lambda field_name, distinct, dkwargs: Count(field_name, distinct=distinct, filter=dkwargs),
'Sum': lambda field_name, distinct, dkwargs: Sum(field_name, distinct=distinct, filter=dkwargs),
'Avg': lambda field_name, distinct, dkwargs: Avg(field_name, distinct=distinct, filter=dkwargs),
'StdDev': lambda field_name, distinct, dkwargs: StdDev(field_name, filter=dkwargs),
'Max': lambda field_name, distinct, dkwargs: Max(field_name, filter=dkwargs),
'Min': lambda field_name, distinct, dkwargs: Min(field_name, filter=dkwargs),
'Variance': lambda field_name, distinct, dkwargs: Variance(field_name, filter=dkwargs),
}
aggregate_dict['agg_%i' % i] = operation[self.type_operation_field_name]
aggregate_dict['agg_%i' % i] = operation[self.type_operation_field_name](self.operation_field_name, self.distinct, dkwargs)

# TODO: maybe backport values_list support back to django-qsstats-magic and use it again for the query
time_range = {'%s__range' % self.date_field_name: (time_since, time_until)}
Expand Down Expand Up @@ -444,6 +444,8 @@ def get_multi_time_series(self, configuration, time_since, time_until, interval,
else:
serie = self.get_time_series(configuration, all_criteria, request, time_since, time_until, interval)
for time, value in serie:
if type(time) == date:
time = datetime.combine(time, datetime.min.time())
series[time] = {'': value}
names = {'': ''}

Expand Down
59 changes: 59 additions & 0 deletions admin_tools_stats/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,65 @@ def test_get_multi_series(self):
}
self.assertDictEqual(serie, testing_data)

@override_settings(USE_TZ=False)
def test_get_multi_series_distinct_count(self):
"""Test function to check DashboardStats.get_multi_time_series() with distinct count."""
stats = mommy.make(
'DashboardStats',
model_name="User",
date_field_name='date_joined',
model_app_name="auth",
type_operation_field_name="Count",
distinct=True,
operation_field_name='first_name',
)
mommy.make('User', date_joined=datetime.date(2010, 10, 10), first_name="Foo")
mommy.make('User', date_joined=datetime.date(2010, 10, 10), first_name="Foo")
mommy.make('User', date_joined=datetime.date(2010, 10, 10), first_name="Bar")
time_since = datetime.date(2010, 10, 8)
time_until = datetime.date(2010, 10, 12)

interval = "days"
serie = stats.get_multi_time_series({}, time_since, time_until, interval)
testing_data = {
datetime.datetime(2010, 10, 8, 0, 0): {'': 0},
datetime.datetime(2010, 10, 9, 0, 0): {'': 0},
datetime.datetime(2010, 10, 10, 0, 0): {'': 2},
datetime.datetime(2010, 10, 11, 0, 0): {'': 0},
datetime.datetime(2010, 10, 12, 0, 0): {'': 0},
}
self.assertDictEqual(serie, testing_data)

@override_settings(USE_TZ=False)
def test_get_multi_series_distinct_functions(self):
"""Test function to check DashboardStats.get_multi_time_series() with various functions."""
for func, result in (
("Sum", 15),
("Avg", 5),
("Min", 1),
("Max", 12),
("StdDev", 4.96655480858378),
("Variance", 24.666666666666668),
("AvgCountPerInstance", 1),
):
stats = mommy.make(
'DashboardStats',
model_name="TestKid",
date_field_name='birthday',
model_app_name="demoproject",
type_operation_field_name=func,
operation_field_name='age',
)
mommy.make('TestKid', birthday=datetime.date(2010, 10, 10), age=12)
mommy.make('TestKid', birthday=datetime.date(2010, 10, 10), age=1)
mommy.make('TestKid', birthday=datetime.date(2010, 10, 10), age=2)
time_since = datetime.date(2010, 10, 9)
time_until = datetime.date(2010, 10, 10)

interval = "days"
serie = stats.get_multi_time_series({}, time_since, time_until, interval)
self.assertEqual(serie[datetime.datetime(2010, 10, 10, 0, 0)][''], result, "Bad value for function %s" % func),

@override_settings(USE_TZ=False)
def test_get_multi_series_dynamic_field_name(self):
"""Test function to check DashboardStats.get_multi_time_series() with dynamic criteria mapping"""
Expand Down

0 comments on commit 21a13ed

Please sign in to comment.