diff --git a/superset/jinja_context.py b/superset/jinja_context.py index 7863809dfd30..33cfe9a2fcf7 100644 --- a/superset/jinja_context.py +++ b/superset/jinja_context.py @@ -24,6 +24,7 @@ from superset import jinja_base_context from superset.extensions import jinja_context_manager +from superset.utils import core as utils def url_param(param: str, default: Optional[str] = None) -> Optional[Any]: @@ -94,18 +95,16 @@ def filter_values(column: str, default: Optional[str] = None) -> List[str]: :return: returns a list of filter values """ form_data = json.loads(request.form.get("form_data", "{}")) + utils.harmonize_query_filters(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: - if isinstance(f["val"], list): - for v in f["val"]: - return_val.append(v) - else: - return_val.append(f["val"]) + for f in form_data.get("filters", {}): + if f["col"] == column: + if isinstance(f["val"], list): + for v in f["val"]: + return_val.append(v) + else: + return_val.append(f["val"]) if return_val: return return_val diff --git a/superset/utils/core.py b/superset/utils/core.py index e1ab257fcfa4..f4c57610a077 100644 --- a/superset/utils/core.py +++ b/superset/utils/core.py @@ -1177,6 +1177,17 @@ def split_adhoc_filters_into_base_filters(fd): fd["filters"] = simple_where_filters +def harmonize_query_filters(form_data: Dict[str, Any]) -> None: + """ + Converts all filters in form_data into base filters. + + :param form_data: parsed form data from request to be mutated + """ + convert_legacy_filters_into_adhoc(form_data) + merge_extra_filters(form_data) + split_adhoc_filters_into_base_filters(form_data) + + def get_username() -> Optional[str]: """Get username if within the flask context, otherwise return noffin'""" try: diff --git a/superset/views/core.py b/superset/views/core.py index 02fd207486c3..a4c175052a45 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -833,8 +833,7 @@ def explore(self, datasource_type=None, datasource_id=None): form_data["datasource"] = str(datasource_id) + "__" + datasource_type # On explore, merge legacy and extra filters into the form data - utils.convert_legacy_filters_into_adhoc(form_data) - utils.merge_extra_filters(form_data) + utils.harmonize_query_filters(form_data) # merge request url params if request.method == "GET": diff --git a/superset/viz.py b/superset/viz.py index f17f234f4bfe..b01c80e3befc 100644 --- a/superset/viz.py +++ b/superset/viz.py @@ -51,12 +51,7 @@ from superset.models.helpers import QueryResult from superset.typing import VizData from superset.utils import core as utils -from superset.utils.core import ( - DTTM_ALIAS, - JS_MAX_INTEGER, - merge_extra_filters, - to_adhoc, -) +from superset.utils.core import DTTM_ALIAS, JS_MAX_INTEGER, to_adhoc if TYPE_CHECKING: from superset.connectors.base.models import BaseDatasource @@ -280,15 +275,10 @@ def df_metrics_to_num(self, df): if dtype.type == np.object_ and col in metrics: df[col] = pd.to_numeric(df[col], errors="coerce") - def process_query_filters(self): - utils.convert_legacy_filters_into_adhoc(self.form_data) - merge_extra_filters(self.form_data) - utils.split_adhoc_filters_into_base_filters(self.form_data) - def query_obj(self) -> Dict[str, Any]: """Building a query object""" form_data = self.form_data - self.process_query_filters() + utils.harmonize_query_filters(form_data) gb = form_data.get("groupby") or [] metrics = self.all_metrics or [] columns = form_data.get("columns") or [] diff --git a/tests/macro_tests.py b/tests/macro_tests.py index 1b9b66ec3090..f1fa1c844c03 100644 --- a/tests/macro_tests.py +++ b/tests/macro_tests.py @@ -45,10 +45,25 @@ def test_filter_values_macro(self): "filters": [{"col": "my_special_filter", "op": "in", "val": "savage"}], } + form_data5 = { + "adhoc_filters": [ + { + "expressionType": "SIMPLE", + "subject": "my_special_filter", + "operator": "in", + "comparator": ["bar"], + "clause": "WHERE", + "sqlExpression": None, + "fromFormData": True, + } + ] + } + data1 = {"form_data": json.dumps(form_data1)} data2 = {"form_data": json.dumps(form_data2)} data3 = {"form_data": json.dumps(form_data3)} data4 = {"form_data": json.dumps(form_data4)} + data5 = {"form_data": json.dumps(form_data5)} with app.test_request_context(data=data1): filter_values = jinja_context.filter_values("my_special_filter") @@ -75,3 +90,7 @@ def test_filter_values_macro(self): with app.test_request_context(data=data4): filter_values = jinja_context.filter_values("my_special_filter") self.assertEqual(filter_values, ["savage", "foo"]) + + with app.test_request_context(data=data5): + filter_values = jinja_context.filter_values("my_special_filter") + self.assertEqual(filter_values, ["bar"])