diff --git a/superset/utils.py b/superset/utils.py index 42f2da3aaf031..469bbc26cfc7a 100644 --- a/superset/utils.py +++ b/superset/utils.py @@ -668,8 +668,8 @@ def get_celery_app(config): def merge_extra_filters(form_data): # extra_filters are temporary/contextual filters that are external # to the slice definition. We use those for dynamic interactive - # filters like the ones emitted by the 'Filter Box' visualization - if form_data.get('extra_filters'): + # filters like the ones emitted by the "Filter Box" visualization + if 'extra_filters' in form_data: # __form and __to are special extra_filters that target time # boundaries. The rest of extra_filters are simple # [column_name in list_of_values]. `__` prefix is there to avoid diff --git a/superset/viz.py b/superset/viz.py index e1ebe742d4a0a..8a90c81868b08 100644 --- a/superset/viz.py +++ b/superset/viz.py @@ -220,7 +220,9 @@ def get_json(self, force=False): @property def cache_key(self): - s = str([(k, self.form_data[k]) for k in sorted(self.form_data.keys())]) + form_data = self.form_data.copy() + merge_extra_filters(form_data) + s = str([(k, form_data[k]) for k in sorted(form_data.keys())]) return hashlib.md5(s.encode('utf-8')).hexdigest() def get_annotations(self): diff --git a/tests/utils_tests.py b/tests/utils_tests.py index 1d5cc65fab1c8..f6d1901d120d4 100644 --- a/tests/utils_tests.py +++ b/tests/utils_tests.py @@ -61,9 +61,9 @@ def test_merge_extra_filters(self): expected = {'A': 1, 'B': 2, 'c': 'test'} merge_extra_filters(form_data) self.assertEquals(form_data, expected) - # does nothing if empty extra_filters + # empty extra_filters form_data = {'A': 1, 'B': 2, 'c': 'test', 'extra_filters': []} - expected = {'A': 1, 'B': 2, 'c': 'test', 'extra_filters': []} + expected = {'A': 1, 'B': 2, 'c': 'test', 'filters': []} merge_extra_filters(form_data) self.assertEquals(form_data, expected) # copy over extra filters into empty filters