This is an automated email from the ASF dual-hosted git repository.
maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push:
new 041fe52 Adds a new macro to allow getting filter values easily (#5547)
041fe52 is described below
commit 041fe520281730daf67a338589ede748280086f0
Author: Manuel Silva <[email protected]>
AuthorDate: Tue Sep 18 02:36:47 2018 +1000
Adds a new macro to allow getting filter values easily (#5547)
* Adds new macro to get filter values from "filters" and "extra_filters"
Adds test for filter_values macro
Adds doco for filter_values
Changes filter_values return type to be a list rather than string
* Makes return value type consistent
- filter_values always return a list
---
docs/sqllab.rst | 2 ++
superset/jinja_context.py | 45 +++++++++++++++++++++++++++++++-
tests/macro_tests.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/docs/sqllab.rst b/docs/sqllab.rst
index 9230b2c..2ba9ac2 100644
--- a/docs/sqllab.rst
+++ b/docs/sqllab.rst
@@ -67,6 +67,8 @@ Superset's Jinja context:
.. autofunction:: superset.jinja_context.url_param
+.. autofunction:: superset.jinja_context.filter_values
+
Extending macros
''''''''''''''''
diff --git a/superset/jinja_context.py b/superset/jinja_context.py
index b700515..27104cc 100644
--- a/superset/jinja_context.py
+++ b/superset/jinja_context.py
@@ -61,8 +61,50 @@ def current_username():
return g.user.username
-class BaseTemplateProcessor(object):
+def filter_values(column, default=None):
+ """ Gets a values for a particular filter as a list
+
+ This is useful if:
+ - you want to use a filter box to filter a query where the name of
filter box
+ column doesn't match the one in the select statement
+ - you want to have the ability for filter inside the main query for
speed purposes
+
+ This searches for "filters" and "extra_filters" in form_data for a match
+
+ Usage example:
+ * SELECT action, count(*) as times
+ FROM logs
+ WHERE action in ( {{ "'" + "','".join(filter_values('action_type')) +
"'" )
+ GROUP BY 1
+
+ :param column: column/filter name to lookup
+ :type column: str
+ :param default: default value to return if there's no matching columns
+ :type default: str
+ :return: returns a list of filter values
+ :rtype: list
+ """
+ form_data = json.loads(request.form.get('form_data', '{}'))
+ return_val = []
+ for filter_type in ['filters', 'extra_filters']:
+ if filter_type not in form_data:
+ continue
+
+ for f in form_data[filter_type]:
+ if f['col'] == column:
+ for v in f['val']:
+ return_val.append(v)
+
+ if return_val:
+ return return_val
+ if default:
+ return [default]
+ else:
+ return []
+
+
+class BaseTemplateProcessor(object):
"""Base class for database-specific jinja context
There's this bit of magic in ``process_template`` that instantiates only
@@ -90,6 +132,7 @@ class BaseTemplateProcessor(object):
'url_param': url_param,
'current_user_id': current_user_id,
'current_username': current_username,
+ 'filter_values': filter_values,
'form_data': {},
}
self.context.update(kwargs)
diff --git a/tests/macro_tests.py b/tests/macro_tests.py
new file mode 100644
index 0000000..4f77a68
--- /dev/null
+++ b/tests/macro_tests.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+from __future__ import unicode_literals
+
+from flask import json
+from tests.base_tests import SupersetTestCase
+
+from superset import app
+from superset import jinja_context
+
+
+class MacroTestCase(SupersetTestCase):
+
+ def test_filter_values_macro(self):
+ form_data1 = {
+ 'extra_filters': [
+ {'col': 'my_special_filter', 'op': 'in', 'val': ['foo']},
+ ],
+ 'filters': [
+ {'col': 'my_special_filter2', 'op': 'in', 'val': ['bar']},
+ ],
+ }
+
+ form_data2 = {
+ 'extra_filters': [
+ {'col': 'my_special_filter', 'op': 'in', 'val': ['foo',
'bar']},
+ ],
+ }
+
+ form_data3 = {
+ 'extra_filters': [
+ {'col': 'my_special_filter', 'op': 'in', 'val': ['foo',
'bar']},
+ ],
+ 'filters': [
+ {'col': 'my_special_filter', 'op': 'in', 'val': ['savage']},
+ ],
+ }
+
+ data1 = {'form_data': json.dumps(form_data1)}
+ data2 = {'form_data': json.dumps(form_data2)}
+ data3 = {'form_data': json.dumps(form_data3)}
+
+ with app.test_request_context(data=data1):
+ filter_values = jinja_context.filter_values('my_special_filter')
+ self.assertEqual(filter_values, ['foo'])
+
+ filter_values = jinja_context.filter_values('my_special_filter2')
+ self.assertEqual(filter_values, ['bar'])
+
+ filter_values = jinja_context.filter_values('')
+ self.assertEqual(filter_values, [])
+
+ with app.test_request_context(data=data2):
+ filter_values = jinja_context.filter_values('my_special_filter')
+ self.assertEqual(filter_values, ['foo', 'bar'])
+
+ with app.test_request_context(data=data3):
+ filter_values = jinja_context.filter_values('my_special_filter')
+ self.assertEqual(filter_values, ['savage', 'foo', 'bar'])
+
+ with app.test_request_context():
+ filter_values = jinja_context.filter_values('nonexistent_filter',
'foo')
+ self.assertEqual(filter_values, ['foo'])