diff --git a/combo/apps/dataviz/models.py b/combo/apps/dataviz/models.py index 09553022..a4f36dcc 100644 --- a/combo/apps/dataviz/models.py +++ b/combo/apps/dataviz/models.py @@ -32,6 +32,7 @@ from django.urls import reverse from django.utils import timezone from django.utils.dates import WEEKDAYS from django.utils.encoding import force_text +from django.utils.functional import cached_property from django.utils.translation import gettext from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ungettext @@ -311,10 +312,10 @@ class ChartNgCell(CellBase): resp, not_found_code='statistic_data_not_found', invalid_code='statistic_url_invalid' ) - def get_statistic_data(self, request=None, raise_if_not_cached=False, invalidate_cache=False): + def get_statistic_data(self, raise_if_not_cached=False, invalidate_cache=False): return requests.get( self.statistic.url, - params=self.get_filter_params(request), + params=self.get_filter_params(), cache_duration=300, remote_service='auto', without_user=True, @@ -323,9 +324,9 @@ class ChartNgCell(CellBase): invalidate_cache=invalidate_cache, ) - def get_chart(self, width=None, height=None, request=None, raise_if_not_cached=False): - transaction.on_commit(lambda: spooler.refresh_statistics_data(cell_pk=self.pk, request=request)) - response = self.get_statistic_data(request=request, raise_if_not_cached=raise_if_not_cached) + def get_chart(self, width=None, height=None, raise_if_not_cached=False): + transaction.on_commit(lambda: spooler.refresh_statistics_data(cell_pk=self.pk)) + response = self.get_statistic_data(raise_if_not_cached) response.raise_for_status() response = response.json() @@ -385,8 +386,8 @@ class ChartNgCell(CellBase): return chart - def get_filter_params(self, request=None): - params = {k: self.evaluate_filter_value(v, request) for k, v in self.filter_params.items() if v} + def get_filter_params(self): + params = {k: self.evaluate_filter_value(v) for k, v in self.filter_params.items() if v} now = timezone.now().date() if self.time_range == 'current-year': @@ -423,11 +424,11 @@ class ChartNgCell(CellBase): params['end'] = self.time_range_end elif self.time_range == 'range-template': if self.time_range_start_template: - start = self.evaluate_range_template(self.time_range_start_template, request) + start = self.evaluate_range_template(self.time_range_start_template) if start: params['start'] = start if self.time_range_end_template: - end = self.evaluate_range_template(self.time_range_end_template, request) + end = self.evaluate_range_template(self.time_range_end_template) if end: params['end'] = end if 'time_interval' in params and not self.statistic.has_native_support_for_interval( @@ -436,18 +437,18 @@ class ChartNgCell(CellBase): params['time_interval'] = 'day' return params - def evaluate_range_template(self, value, request): + def evaluate_range_template(self, value): if value in self.page.extra_variables: value = self.page.extra_variables[value].strip('{ }') - context = self.get_request_context(request) + context = self.request_context context.update({'now': datetime.now, 'today': datetime.now}) try: return Template('{{ %s|date:"Y-m-d" }}' % value).render(context) except (VariableDoesNotExist, TemplateSyntaxError): return None - def evaluate_filter_value(self, value, request): + def evaluate_filter_value(self, value): if isinstance(value, list) or not value.startswith('variable:'): return value @@ -456,14 +457,15 @@ class ChartNgCell(CellBase): except KeyError: raise MissingVariable - return Template(variable).render(self.get_request_context(request)) + return Template(variable).render(self.request_context) - def get_request_context(self, request): - if request is None: + @cached_property + def request_context(self): + if not getattr(self, '_request', None): raise MissingRequest - ctx = RequestContext(request, getattr(request, 'extra_context', {})) - ctx['request'] = request + ctx = RequestContext(self._request, getattr(self._request, 'extra_context', {})) + ctx['request'] = self._request return ctx def parse_response(self, response, chart): @@ -716,9 +718,10 @@ class ChartNgCell(CellBase): def available_filters(self): return self.statistic.filters + self.subfilters - def update_subfilters(self, request=None): + def update_subfilters(self): + self._request = get_request() try: - response = self.get_statistic_data(request=request or get_request()) + response = self.get_statistic_data() except (TemplateSyntaxError, VariableDoesNotExist): return diff --git a/combo/apps/dataviz/views.py b/combo/apps/dataviz/views.py index ebc325c5..1b9292d8 100644 --- a/combo/apps/dataviz/views.py +++ b/combo/apps/dataviz/views.py @@ -69,11 +69,11 @@ class DatavizGraphView(DetailView): except signing.BadSignature: return HttpResponseBadRequest('bad signature') + form.instance._request = request try: chart = form.instance.get_chart( width=int(request.GET['width']) if request.GET.get('width') else None, height=int(request.GET['height']) if request.GET.get('height') else int(self.cell.height), - request=request, ) except UnsupportedDataSet: return self.error(_('Unsupported dataset.')) diff --git a/combo/utils/spooler.py b/combo/utils/spooler.py index 12ae0421..ac63a0c5 100644 --- a/combo/utils/spooler.py +++ b/combo/utils/spooler.py @@ -94,8 +94,8 @@ def refresh_statistics_list(): @tenantspool -def refresh_statistics_data(cell_pk, request): - from combo.apps.dataviz.models import ChartNgCell, MissingVariable +def refresh_statistics_data(cell_pk): + from combo.apps.dataviz.models import ChartNgCell, MissingRequest, MissingVariable try: cell = ChartNgCell.objects.get(pk=cell_pk) @@ -103,9 +103,9 @@ def refresh_statistics_data(cell_pk, request): return try: - cell.get_statistic_data(request=request, invalidate_cache=True) - except MissingVariable: + cell.get_statistic_data(invalidate_cache=True) + except (MissingRequest, MissingVariable): return if cell.statistic.service_slug != 'bijoe': - cell.update_subfilters(request) + cell.update_subfilters() diff --git a/tests/test_dataviz.py b/tests/test_dataviz.py index e17d6a3d..a32d5949 100644 --- a/tests/test_dataviz.py +++ b/tests/test_dataviz.py @@ -2638,29 +2638,23 @@ def test_spooler_refresh_statistics_data(new_api_statistics): cell.statistic = Statistic.objects.get(slug='one-serie') cell.save() - refresh_statistics_data(cell.pk, request=mock.MagicMock()) + refresh_statistics_data(cell.pk) assert len(new_api_mock.call['requests']) == 1 - refresh_statistics_data(cell.pk, request=mock.MagicMock()) + refresh_statistics_data(cell.pk) assert len(new_api_mock.call['requests']) == 2 - # variables can be evaluated in spooler + # variables cannot be evaluated in spooler page.extra_variables = {'test': 'test'} page.save() cell.filter_params = {'ou': 'variable:test'} cell.save() - refresh_statistics_data(cell.pk, request=mock.MagicMock()) - assert len(new_api_mock.call['requests']) == 3 - - # missing variable - cell.filter_params = {'ou': 'variable:unknown'} - cell.save() - refresh_statistics_data(cell.pk, request=mock.MagicMock()) - assert len(new_api_mock.call['requests']) == 3 + refresh_statistics_data(cell.pk) + assert len(new_api_mock.call['requests']) == 2 ChartNgCell.objects.all().delete() - refresh_statistics_data(cell.pk, request=mock.MagicMock()) - assert len(new_api_mock.call['requests']) == 3 + refresh_statistics_data(cell.pk) + assert len(new_api_mock.call['requests']) == 2 @with_httmock(bijoe_mock) @@ -2670,7 +2664,7 @@ def test_spooler_refresh_statistics_data_bijoe(statistics): cell.statistic = Statistic.objects.get(slug='example') cell.save() - refresh_statistics_data(cell.pk, request=None) + refresh_statistics_data(cell.pk) assert len(bijoe_mock.call['requests']) == 1