diff --git a/datasette/facets.py b/datasette/facets.py index 76d73e51..9677e971 100644 --- a/datasette/facets.py +++ b/datasette/facets.py @@ -499,22 +499,27 @@ class ManyToManyFacet(Facet): "outgoing" ] if len(other_table_outgoing_foreign_keys) == 2: - destination_table = [ + fk_from_middle_table_to_other_table = [ t for t in other_table_outgoing_foreign_keys if t["other_table"] != self.table - ][0]["other_table"] + ][0] + destination_table = fk_from_middle_table_to_other_table["other_table"] + middle_table = other_table + m2m_config = json.dumps([ + middle_table, destination_table + ], separators=(",", ":"), sort_keys=True) # Only suggest if it's not selected already - if ("_facet_m2m", destination_table) in args: + if ("_facet_m2m", m2m_config) in args: continue suggested_facets.append( { - "name": destination_table, + "name": "{}.{}".format(middle_table, destination_table), "type": "m2m", "toggle_url": self.ds.absolute_url( self.request, path_with_added_args( - self.request, {"_facet_m2m": destination_table} + self.request, {"_facet_m2m": m2m_config} ), ), } @@ -536,10 +541,10 @@ class ManyToManyFacet(Facet): config = source_and_config["config"] source = source_and_config["source"] # The destination_table is specified in the _facet_m2m=xxx parameter - destination_table = config.get("column") or config["simple"] + m2m_config = config.get("column") or config["simple"] # Find middle table - it has fks to self.table AND destination_table + middle_table, destination_table = json.loads(m2m_config) fks = None - middle_table = None for fk in incoming: other_table = fk["other_table"] other_table_outgoing_foreign_keys = all_foreign_keys[other_table][ @@ -554,7 +559,6 @@ class ManyToManyFacet(Facet): and len(other_table_outgoing_foreign_keys) == 2 ): fks = other_table_outgoing_foreign_keys - middle_table = other_table break if middle_table is None or fks is None: return [], [] diff --git a/tests/test_html.py b/tests/test_html.py index f76f98b9..7e8eaea5 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -385,12 +385,16 @@ def test_facet_display(app_client): ] == actual -def test_facets_persist_through_filter_form(app_client): - response = app_client.get("/fixtures/facetable?_facet=planet_int&_facet=city_id") +@pytest.mark.parametrize("path,expected_hiddens", [ + ("/fixtures/facetable?_facet=planet_int&_facet=city_id", [("_facet", "city_id"), ("_facet", "planet_int")]), + ("/fixtures/roadside_attractions?_facet_m2m=attraction_characteristic", [("_facet", "city_id"), ("_facet", "planet_int")]), +]) +def test_facets_persist_through_filter_form(app_client, path, expected_hiddens): + response = app_client.get(path) assert response.status == 200 inputs = Soup(response.body, "html.parser").find("form").findAll("input") hiddens = [i for i in inputs if i["type"] == "hidden"] - assert [("_facet", "city_id"), ("_facet", "planet_int")] == [ + assert expected_hiddens == [ (hidden["name"], hidden["value"]) for hidden in hiddens ]