superset-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From maximebeauche...@apache.org
Subject [incubator-superset] branch master updated: Adds a new macro to allow getting filter values easily (#5547)
Date Mon, 17 Sep 2018 16:36:55 GMT
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 <manuel@mjs.me>
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'])


Mime
View raw message