add support for string columns (fixes #29768)
This commit is contained in:
parent
973f793f0a
commit
6974f1f56e
|
@ -254,14 +254,20 @@ class Dimension(Base):
|
|||
filter_values = [filter_values]
|
||||
if not filter_values:
|
||||
return '', []
|
||||
is_none = None in filter_values
|
||||
filter_values = [v for v in filter_values if v is not None]
|
||||
if self.type == 'integer':
|
||||
values = map(int, filter_values)
|
||||
values = [int(v) for v in filter_values]
|
||||
else:
|
||||
values = filter_values
|
||||
s = ', '.join(['%s'] * len(values))
|
||||
if self.filter_expression:
|
||||
return self.filter_expression % s, values
|
||||
return '%s IN (%s)' % (value, s), values
|
||||
expression = self.filter_expression % s
|
||||
else:
|
||||
expression = '%s IN (%s)' % (value, s)
|
||||
if is_none:
|
||||
expression = '((%s) OR (%s IS NULL))' % (expression, value)
|
||||
return expression, values
|
||||
|
||||
|
||||
def join_kind(kind):
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<tr>
|
||||
{% for value in row %}
|
||||
{% comment %}Only django 1.10 allow is None/True/False{% endcomment %}
|
||||
<td>{% if value|stringformat:"r" == "None" %}0{% elif value|stringformat:"r" == "True" %}{% trans "Oui" %}{% elif value|stringformat:"r" == "False" %}{% trans "Non" %}{% else %}{{ value }}{% endif %}</td>
|
||||
<td>{{ value }}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
|
|
@ -15,10 +15,12 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
from django import forms
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils import six
|
||||
from django.forms import ModelForm, TextInput, NullBooleanField
|
||||
from django.conf import settings
|
||||
|
||||
|
@ -183,9 +185,23 @@ class CubeForm(forms.Form):
|
|||
self.base_fields[field_name] = NullBooleanField(
|
||||
label=dimension.label.capitalize(), required=False)
|
||||
else:
|
||||
self.base_fields[field_name] = forms.MultipleChoiceField(
|
||||
members = []
|
||||
for _id, label in dimension.members:
|
||||
members.append((_id, six.text_type(_id), label))
|
||||
members.append((None, '__none__', _('None')))
|
||||
|
||||
def coercion_function(members):
|
||||
def f(v):
|
||||
for value, s, label in members:
|
||||
if v == s:
|
||||
return value
|
||||
return None
|
||||
return f
|
||||
|
||||
self.base_fields[field_name] = forms.TypedMultipleChoiceField(
|
||||
label=dimension.label.capitalize(),
|
||||
choices=dimension.members,
|
||||
choices=[(s, label) for v, s, label in members],
|
||||
coerce=coercion_function(members),
|
||||
required=False,
|
||||
widget=build_select2_multiple_widget())
|
||||
|
||||
|
|
|
@ -159,6 +159,12 @@ class Visualization(object):
|
|||
if not s:
|
||||
s = 'moins d\'1 heure'
|
||||
value = s
|
||||
elif value is not None and cell['type'] == 'bool':
|
||||
value = _('Yes') if value else _('No')
|
||||
elif value is None and cell['type'] in ('duration','integer'):
|
||||
value = 0
|
||||
elif value is None and cell['type'] != 'integer':
|
||||
value = _('None')
|
||||
cell['value'] = value
|
||||
return data
|
||||
|
||||
|
@ -179,12 +185,21 @@ class Visualization(object):
|
|||
def table(self):
|
||||
table = []
|
||||
if len(self.drilldown) == 2:
|
||||
if self.measure.type == 'integer':
|
||||
default = 0
|
||||
elif self.measure.type == 'duration':
|
||||
default = '0 s'
|
||||
elif self.measure.type == 'percent':
|
||||
default = '0 %'
|
||||
else:
|
||||
raise NotImplementedError(self.measure.type)
|
||||
|
||||
x_labels = [x.label for x in self.drilldown_x.members]
|
||||
y_labels = [y.label for y in self.drilldown_y.members]
|
||||
used_x_label = set()
|
||||
used_y_label = set()
|
||||
|
||||
grid = {(x, y): None for x in x_labels for y in y_labels}
|
||||
grid = {(x, y): default for x in x_labels for y in y_labels}
|
||||
|
||||
for row in self.stringified():
|
||||
x_label = unicode(row[0]['value'])
|
||||
|
|
|
@ -157,6 +157,12 @@
|
|||
"value": "outercategory.id",
|
||||
"order_by": "outercategory.ord",
|
||||
"value_label": "outercategory.label"
|
||||
},
|
||||
{
|
||||
"name": "string",
|
||||
"label": "String",
|
||||
"type": "string",
|
||||
"value": "string"
|
||||
}
|
||||
],
|
||||
"measures": [
|
||||
|
|
|
@ -25,7 +25,8 @@ CREATE TABLE facts (
|
|||
innersubcategory_id integer references schema1.subcategory(id),
|
||||
leftsubcategory_id integer references schema1.subcategory(id),
|
||||
rightsubcategory_id integer references schema1.subcategory(id),
|
||||
outersubcategory_id integer references schema1.subcategory(id)
|
||||
outersubcategory_id integer references schema1.subcategory(id),
|
||||
string varchar
|
||||
);
|
||||
|
||||
INSERT INTO category (ord, label) VALUES
|
||||
|
@ -45,21 +46,21 @@ INSERT INTO subcategory (category_id, ord, label) VALUES
|
|||
(3, 0, 'subé9');
|
||||
|
||||
|
||||
INSERT INTO facts (date, datetime, integer, boolean, cnt, innersubcategory_id, leftsubcategory_id, rightsubcategory_id, outersubcategory_id) VALUES
|
||||
('2017-01-01', '2017-01-01 10:00', 1, FALSE, 10, 1, 1, 1, 1),
|
||||
('2017-01-02', '2017-01-02 10:00', 1, TRUE, 10, 3, 3, 3, 3),
|
||||
('2017-01-03', '2017-01-03 10:00', 1, FALSE, 10, NULL, NULL, NULL, NULL),
|
||||
('2017-01-04', '2017-01-04 10:00', 1, FALSE, 10, 1, 1, 1, 1),
|
||||
('2017-01-05', '2017-01-05 10:00', 1, TRUE, 10, 1, 1, 1, 1),
|
||||
('2017-01-06', '2017-01-06 10:00', 1, FALSE, 10, 1, 1, 1, 1),
|
||||
('2017-01-07', '2017-01-07 10:00', 1, TRUE, 10, 1, 1, 1, 1),
|
||||
('2017-01-08', '2017-01-08 10:00', 1, FALSE, 10, 1, 1, 1, 1),
|
||||
('2017-01-09', '2017-01-09 10:00', 1, TRUE, 10, 1, 1, 1, 1),
|
||||
('2017-01-10', '2017-01-10 10:00', 1, FALSE, 10, 1, 1, 1, 1),
|
||||
('2017-02-01', '2017-02-01 10:00', 1, TRUE, 10, 1, 1, 1, 1),
|
||||
('2017-03-01', '2017-03-01 10:00', 1, FALSE, 10, 1, 1, 1, 1),
|
||||
('2017-04-01', '2017-04-01 10:00', 1, TRUE, 10, 1, 1, 1, 1),
|
||||
('2017-05-01', '2017-05-01 10:00', 1, FALSE, 10, 1, 1, 1, 1),
|
||||
('2017-06-01', '2017-06-01 10:00', 1, TRUE, 10, 1, 1, 1, 1),
|
||||
('2017-07-01', '2017-07-01 10:00', 1, FALSE, 10, 1, 1, 1, 1),
|
||||
('2017-08-01', '2017-08-01 10:00', 1, TRUE, 10, 1, 1, 1, 1);
|
||||
INSERT INTO facts (date, datetime, integer, boolean, cnt, innersubcategory_id, leftsubcategory_id, rightsubcategory_id, outersubcategory_id, string) VALUES
|
||||
('2017-01-01', '2017-01-01 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'a'),
|
||||
('2017-01-02', '2017-01-02 10:00', 1, TRUE, 10, 3, 3, 3, 3, 'b'),
|
||||
('2017-01-03', '2017-01-03 10:00', 1, FALSE, 10, NULL, NULL, NULL, NULL, 'a'),
|
||||
('2017-01-04', '2017-01-04 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'a'),
|
||||
('2017-01-05', '2017-01-05 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'c'),
|
||||
('2017-01-06', '2017-01-06 10:00', 1, FALSE, 10, 1, 1, 1, 1, NULL),
|
||||
('2017-01-07', '2017-01-07 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'a'),
|
||||
('2017-01-08', '2017-01-08 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'a'),
|
||||
('2017-01-09', '2017-01-09 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'a'),
|
||||
('2017-01-10', '2017-01-10 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'a'),
|
||||
('2017-02-01', '2017-02-01 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'a'),
|
||||
('2017-03-01', '2017-03-01 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'c'),
|
||||
('2017-04-01', '2017-04-01 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'a'),
|
||||
('2017-05-01', '2017-05-01 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'a'),
|
||||
('2017-06-01', '2017-06-01 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'c'),
|
||||
('2017-07-01', '2017-07-01 10:00', 1, FALSE, 10, 1, 1, 1, 1, 'a'),
|
||||
('2017-08-01', '2017-08-01 10:00', 1, TRUE, 10, 1, 1, 1, 1, 'b');
|
||||
|
|
|
@ -68,3 +68,18 @@ def test_boolean_dimension(schema1, app, admin):
|
|||
form.set('filter__boolean', [o[0] for o in form.fields['filter__boolean'][0].options if o[2] == 'Oui'][0])
|
||||
response = form.submit('visualize')
|
||||
assert get_table(response) == [['Boolean', 'Oui'], ['number of rows', '8']]
|
||||
|
||||
|
||||
def test_string_dimension(schema1, app, admin):
|
||||
login(app, admin)
|
||||
response = app.get('/').follow()
|
||||
response = response.click('Facts 1')
|
||||
form = response.form
|
||||
form.set('representation', 'table')
|
||||
form.set('measure', 'simple_count')
|
||||
form.set('drilldown_x', 'string')
|
||||
response = form.submit('visualize')
|
||||
assert get_table(response) == [['String', 'a', 'b', 'c', 'Aucun(e)'], ['number of rows', '11', '2', '3', '1']]
|
||||
form.set('filter__string', ['a', 'b', '__none__'])
|
||||
response = form.submit('visualize')
|
||||
assert get_table(response) == [['String', 'a', 'b', 'Aucun(e)'], ['number of rows', '11', '2', '1']]
|
||||
|
|
Loading…
Reference in New Issue