diff --git a/datasette/templates/row.html b/datasette/templates/row.html
index 916980b6..c86e979d 100644
--- a/datasette/templates/row.html
+++ b/datasette/templates/row.html
@@ -38,7 +38,7 @@
{% for other in foreign_key_tables %}
-
-
+
{{ "{:,}".format(other.count) }} row{% if other.count == 1 %}{% else %}s{% endif %}
from {{ other.other_column }} in {{ other.other_table }}
diff --git a/datasette/views/table.py b/datasette/views/table.py
index 9fc6afcf..f58b78f5 100644
--- a/datasette/views/table.py
+++ b/datasette/views/table.py
@@ -1120,5 +1120,13 @@ class RowView(RowTableShared):
count = (
foreign_table_counts.get((fk["other_table"], fk["other_column"])) or 0
)
- foreign_key_tables.append({**fk, **{"count": count}})
+ key = fk["other_column"]
+ if key.startswith("_"):
+ key += "__exact"
+ link = "{}?{}={}".format(
+ self.ds.urls.table(database, fk["other_table"]),
+ key,
+ ",".join(pk_values),
+ )
+ foreign_key_tables.append({**fk, **{"count": count, "link": link}})
return foreign_key_tables
diff --git a/tests/test_html.py b/tests/test_html.py
index aaf7da09..a7cb105c 100644
--- a/tests/test_html.py
+++ b/tests/test_html.py
@@ -820,6 +820,34 @@ def test_row_html_no_primary_key(app_client):
]
+@pytest.mark.parametrize(
+ "path,expected_text,expected_link",
+ (
+ (
+ "/fixtures/facet_cities/1",
+ "6 rows from _city_id in facetable",
+ "/fixtures/facetable?_city_id__exact=1",
+ ),
+ (
+ "/fixtures/attraction_characteristic/2",
+ "3 rows from characteristic_id in roadside_attraction_characteristics",
+ "/fixtures/roadside_attraction_characteristics?characteristic_id=2",
+ ),
+ ),
+)
+def test_row_links_from_other_tables(app_client, path, expected_text, expected_link):
+ response = app_client.get(path)
+ assert response.status == 200
+ soup = Soup(response.body, "html.parser")
+ h2 = soup.find("h2")
+ assert h2.text == "Links from other tables"
+ li = h2.findNext("ul").find("li")
+ text = re.sub(r"\s+", " ", li.text.strip())
+ assert text == expected_text
+ link = li.find("a")["href"]
+ assert link == expected_link
+
+
def test_table_html_compound_primary_key(app_client):
response = app_client.get("/fixtures/compound_primary_key")
assert response.status == 200