From 0bb02b6519a6c0ea1724a87853fb8731cf596800 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 28 Nov 2019 20:14:16 +0100 Subject: [PATCH 11/13] schemas: add an absent_label property to Dimension (#38067) Also force lazy strings to unicode in to_json(). --- bijoe/engine.py | 2 ++ bijoe/schemas.py | 18 +++++++++++++++++- tests/test_schemas.py | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 tests/test_schemas.py diff --git a/bijoe/engine.py b/bijoe/engine.py index 2d8435e..3f01dc5 100644 --- a/bijoe/engine.py +++ b/bijoe/engine.py @@ -23,6 +23,7 @@ import collections import psycopg2 from django.core.cache import cache +from django.utils.translation import ugettext_lazy as _ from . import schemas @@ -138,6 +139,7 @@ class SchemaJSONDimension(schemas.Dimension): 'OR ({fact_table}.%s->>\'%s\') IN (%%s))' % (json_field, name)) self.filter_needs_join = False + self.absent_label = _('None') class EngineJSONDimension(EngineDimension): diff --git a/bijoe/schemas.py b/bijoe/schemas.py index 1705384..ae4685b 100644 --- a/bijoe/schemas.py +++ b/bijoe/schemas.py @@ -21,6 +21,8 @@ import decimal import collections from django.utils import six +from django.utils.functional import Promise +from django.utils.translation import ugettext_lazy as _ from .relative_time import RelativeDate @@ -116,6 +118,8 @@ class Base(object): v = types[attr].to_json(v) if isinstance(v, list): v = [x.to_json() if hasattr(x, 'to_json') else x for x in v] + if isinstance(v, Promise): + v = unicode(v) d[attr] = v return d @@ -137,7 +141,7 @@ class Measure(Base): class Dimension(Base): __slots__ = ['name', 'label', 'type', 'join', 'value', 'value_label', 'order_by', 'group_by', 'filter_in_join', 'filter', 'filter_value', - 'filter_needs_join', 'filter_expression'] + 'filter_needs_join', 'filter_expression', 'absent_label'] __types__ = { 'name': str, 'label': unicode, @@ -153,6 +157,7 @@ class Dimension(Base): 'filter_in_join': bool, 'filter_value': str, 'filter_needs_join': bool, + 'absent_label': unicode, } label = None @@ -166,6 +171,17 @@ class Dimension(Base): filter_expression = None filter_needs_join = True members_query = None + absent_label = None + + def __init__(self, **kwargs): + super(Dimension, self).__init__(**kwargs) + if not self.absent_label: + if self.type in ('date', 'integer', 'string'): + self.absent_label = _('None') + elif self.type in ('bool',): + self.absent_label = _('N/A') + else: + raise NotImplementedError('not absent label for type %r' % self.type) @property def dimensions(self): diff --git a/tests/test_schemas.py b/tests/test_schemas.py new file mode 100644 index 0000000..31ddfde --- /dev/null +++ b/tests/test_schemas.py @@ -0,0 +1,38 @@ +# bijoe - BI dashboard +# Copyright (C) 2019 Entr'ouvert +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + + +from __future__ import unicode_literals + +import pytest + +from django.utils.translation import ugettext as _ + +from bijoe.schemas import ( + Dimension, +) + + +def test_absent_label(): + assert Dimension.from_json({'name': 'x', 'value': 'x', 'type': 'integer'}).absent_label == _('None') + assert Dimension.from_json({'name': 'x', 'value': 'x', 'type': 'string'}).absent_label == _('None') + assert Dimension.from_json({'name': 'x', 'value': 'x', 'type': 'bool'}).absent_label == _('N/A') + assert Dimension.from_json( + {'name': 'x', 'value': 'x', 'type': 'boolean', 'absent_label': 'coin'}).absent_label == 'coin' + + with pytest.raises(NotImplementedError): + Dimension.from_json({'name': 'x', 'value': 'x', 'type': 'coin'}).absent_label + -- 2.23.0