diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5baed07..7390f4b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,13 @@
All notable changes to this project will be documented in this file.
+## [0.5.3]
+
+- Enhanced Field prepare flow
+- Add traversing for group_by
+- Allowed tests to run specific tests instead of the whole suit
+- Enhanced templates structure for easier override/customization
+
## [0.5.2]
- Enhanced Time Series Plot total HighChart by accenting the categories
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 56fc773..7362ae4 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -24,7 +24,7 @@
master_doc = 'index'
# The full version, including alpha/beta/rc tags
-release = '0.5.2'
+release = '0.5.3'
# -- General configuration ---------------------------------------------------
diff --git a/runtests.py b/runtests.py
index 001be57..5f753e1 100644
--- a/runtests.py
+++ b/runtests.py
@@ -2,15 +2,28 @@
import os
import sys
+import argparse
import django
from django.conf import settings
from django.test.utils import get_runner
if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description="Run the Django Slick Reporting test suite.")
+ parser.add_argument(
+ 'modules', nargs='*', metavar='module',
+ help='Optional path(s) to test modules; e.g. "i18n" or '
+ '"i18n.tests.TranslationTests.test_lazy_objects".',
+ )
+ options = parser.parse_args()
+
+ options.modules = [os.path.normpath(labels) for labels in options.modules]
+
+
os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.test_settings'
django.setup()
TestRunner = get_runner(settings)
test_runner = TestRunner()
- failures = test_runner.run_tests(["tests"])
+ failures = test_runner.run_tests(options.modules)
+ # failures = test_runner.run_tests(["tests"])
sys.exit(bool(failures))
diff --git a/slick_reporting/__init__.py b/slick_reporting/__init__.py
index efe36c1..1caadbd 100644
--- a/slick_reporting/__init__.py
+++ b/slick_reporting/__init__.py
@@ -1,6 +1,6 @@
default_app_config = 'slick_reporting.apps.ReportAppConfig'
-VERSION = (0, 5, 2)
+VERSION = (0, 5, 3)
-__version__ = '0.5.2'
+__version__ = '0.5.3'
diff --git a/slick_reporting/fields.py b/slick_reporting/fields.py
index 17731a9..fab5031 100644
--- a/slick_reporting/fields.py
+++ b/slick_reporting/fields.py
@@ -110,6 +110,21 @@ def apply_aggregation(self, queryset, group_by=''):
queryset = queryset.aggregate(annotation)
return queryset
+ def init_preparation(self, q_filters=None, kwargs_filters=None, **kwargs):
+ """
+ Called by the generator to preparet he calculation of this field + it's requirements
+ :param q_filters:
+ :param kwargs_filters:
+ :param kwargs:
+ :return:
+ """
+ kwargs_filters = kwargs_filters or {}
+
+ dep_values = self._prepare_dependencies(q_filters, kwargs_filters.copy())
+
+ debit_results, credit_results = self.prepare(q_filters, kwargs_filters, **kwargs)
+ self._cache = debit_results, credit_results, dep_values
+
def prepare(self, q_filters=None, kwargs_filters=None, **kwargs):
"""
This is the first hook where you can customize the calculation away from the Django Query aggregation method
@@ -122,10 +137,6 @@ def prepare(self, q_filters=None, kwargs_filters=None, **kwargs):
:param kwargs:
:return:
"""
- kwargs_filters = kwargs_filters or {}
-
- dep_values = self._prepare_dependencies(q_filters, kwargs_filters.copy())
-
queryset = self.get_queryset()
if q_filters:
queryset = queryset.filter(*q_filters)
@@ -148,8 +159,7 @@ def prepare(self, q_filters=None, kwargs_filters=None, **kwargs):
credit_results = self.apply_aggregation(queryset, self.group_by)
- self._cache = debit_results, credit_results, dep_values
- return debit_results, credit_results, dep_values
+ return debit_results, credit_results
def get_queryset(self):
queryset = self.report_model.objects
@@ -167,15 +177,16 @@ def _prepare_dependencies(self, q_filters=None, extra_filters=None, ):
for dep_class in self._require_classes:
dep = dep_class(self.plus_side_q, self.minus_side_q, self.report_model,
date_field=self.date_field, group_by=self.group_by)
- values[dep.name] = {'results': dep.prepare(q_filters, extra_filters),
+ values[dep.name] = {'results': dep.init_preparation(q_filters, extra_filters),
'instance': dep}
return values
- def resolve(self, current_obj):
+ def resolve(self, current_obj, current_row=None):
'''
Reponsible for getting the exact data from the prepared value
:param cached: the returned data from prepare
- :param current_obj:
+ :param current_obj: he value of group by id
+ :param current_row: the row in iteration
:return: a solid number or value
'''
cached = self._cache
diff --git a/slick_reporting/generator.py b/slick_reporting/generator.py
index 20de4d6..e259e6a 100644
--- a/slick_reporting/generator.py
+++ b/slick_reporting/generator.py
@@ -193,14 +193,20 @@ def __init__(self, report_model=None, main_queryset=None, start_date=None, end_d
# todo validate columns is not empty (if no time series / cross tab)
if self.group_by:
+ group_by_split = self.group_by.split('__')
+ search_field = group_by_split[0]
try:
- self.group_by_field = [x for x in self.report_model._meta.fields if x.name == self.group_by][0]
+ self.group_by_field = [x for x in self.report_model._meta.fields if x.name == search_field][0]
+
except IndexError:
raise ImproperlyConfigured(
f'Can not find group_by field:{self.group_by} in report_model {self.report_model} ')
+ self.focus_field_as_key = self.group_by_field
+ if '__' not in self.group_by:
+ self.group_by_field_attname = self.group_by_field.attname
+ else:
+ self.group_by_field_attname = self.group_by
- self.focus_field_as_key = self.group_by
- self.group_by_field_attname = self.group_by_field.attname
else:
self.focus_field_as_key = None
self.group_by_field_attname = None
@@ -236,17 +242,16 @@ def __init__(self, report_model=None, main_queryset=None, start_date=None, end_d
else:
self.main_queryset = self._apply_queryset_options(main_queryset)
- if type(self.group_by_field) is ForeignKey:
- ids = self.main_queryset.values_list(self.group_by_field.attname).distinct()
+ if type(self.group_by_field) is ForeignKey and '__' not in self.group_by:
+ ids = self.main_queryset.values_list(self.group_by_field_attname).distinct()
self.main_queryset = self.group_by_field.related_model.objects.filter(pk__in=ids).values()
else:
- self.main_queryset = self.main_queryset.distinct().values(self.group_by_field.attname)
+ self.main_queryset = self.main_queryset.distinct().values(self.group_by_field_attname)
else:
if self.time_series_pattern:
self.main_queryset = [{}]
else:
self.main_queryset = self._apply_queryset_options(main_queryset, self.get_database_columns())
-
self._prepare_report_dependencies()
def _apply_queryset_options(self, query, fields=None):
@@ -322,8 +327,7 @@ def _prepare_report_dependencies(self):
if window == 'crosstab':
q_filters = self._construct_crosstab_filter(col_data)
- # print(f'preparing {report_class} for {window}')
- report_class.prepare(q_filters, date_filter)
+ report_class.init_preparation(q_filters, date_filter)
self.report_fields_classes[name] = report_class
def _get_record_data(self, obj, columns):
@@ -359,7 +363,7 @@ def _get_record_data(self, obj, columns):
computation_class = self.report_fields_classes[name]
except KeyError:
continue
- value = computation_class.resolve(group_by_val)
+ value = computation_class.resolve(group_by_val, data)
if self.swap_sign: value = -value
data[name] = value
@@ -402,7 +406,7 @@ def check_columns(cls, columns, group_by, report_model, ):
"""
group_by_model = None
if group_by:
- group_by_field = [x for x in report_model._meta.fields if x.name == group_by][0]
+ group_by_field = [x for x in report_model._meta.fields if x.name == group_by.split('__')[0]][0]
if group_by_field.is_relation:
group_by_model = group_by_field.related_model
else:
@@ -450,7 +454,7 @@ def check_columns(cls, columns, group_by, report_model, ):
}
else:
# A database field
- model_to_use = group_by_model if group_by else report_model
+ model_to_use = group_by_model if group_by and '__' not in group_by else report_model
try:
if '__' in col:
# A traversing link order__client__email
diff --git a/slick_reporting/templates/slick_reporting/base.html b/slick_reporting/templates/slick_reporting/base.html
index b3bcd0c..8c60515 100644
--- a/slick_reporting/templates/slick_reporting/base.html
+++ b/slick_reporting/templates/slick_reporting/base.html
@@ -42,9 +42,9 @@
integrity="JnbsSLBmv2/R0fUmF2XYIcAEMPHEAO51Gitn9IjL4l89uFTIgtLF1+jqIqqd9FSk"
crossorigin="anonymous">
-
-
-
+
{% block js_script %}
{% endblock %}