Skip to content

Commit 8609e3c

Browse files
committed
Expand labels in row view as well
1 parent 8a315f3 commit 8609e3c

3 files changed

Lines changed: 113 additions & 54 deletions

File tree

datasette/views/row.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from datasette.plugins import pm
1313
import json
1414
import sqlite_utils
15-
from .table import display_columns_and_rows, _get_extras
15+
from .table import display_columns_and_rows, expand_labels, _get_extras
1616

1717

1818
class RowView(DataView):
@@ -42,6 +42,11 @@ async def data(self, request, default_labels=False):
4242
if not rows:
4343
raise NotFound(f"Record not found: {pk_values}")
4444

45+
# Expand labeled columns if requested
46+
rows, _ = await expand_labels(
47+
self.ds, db, request, table, columns, rows, default_labels
48+
)
49+
4550
async def template_data():
4651
display_columns, display_rows = await display_columns_and_rows(
4752
self.ds,

datasette/views/table.py

Lines changed: 75 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,72 @@ async def display_columns_and_rows(
335335
return columns, cell_rows
336336

337337

338+
async def expand_labels(
339+
datasette,
340+
db,
341+
request,
342+
table_name,
343+
columns,
344+
rows,
345+
default_labels,
346+
):
347+
"""Expands labeled columns if requested"""
348+
expanded_columns = []
349+
# List of (fk_dict, label_column-or-None) pairs for that table
350+
expandable_columns = []
351+
for fk in await db.foreign_keys_for_table(table_name):
352+
label_column = await db.label_column_for_table(fk["other_table"])
353+
expandable_columns.append((fk, label_column))
354+
355+
columns_to_expand = None
356+
try:
357+
all_labels = value_as_boolean(request.args.get("_labels", ""))
358+
except ValueError:
359+
all_labels = default_labels
360+
# Check for explicit _label=
361+
if "_label" in request.args:
362+
columns_to_expand = request.args.getlist("_label")
363+
if columns_to_expand is None and all_labels:
364+
# expand all columns with foreign keys
365+
columns_to_expand = [fk["column"] for fk, _ in expandable_columns]
366+
367+
if columns_to_expand:
368+
expanded_labels = {}
369+
for fk, _ in expandable_columns:
370+
column = fk["column"]
371+
if column not in columns_to_expand:
372+
continue
373+
if column not in columns:
374+
continue
375+
expanded_columns.append(column)
376+
# Gather the values
377+
column_index = columns.index(column)
378+
values = [row[column_index] for row in rows]
379+
# Expand them
380+
expanded_labels.update(
381+
await datasette.expand_foreign_keys(
382+
request.actor, db.name, table_name, column, values
383+
)
384+
)
385+
if expanded_labels:
386+
# Rewrite the rows
387+
new_rows = []
388+
for row in rows:
389+
new_row = CustomRow(columns)
390+
for column in row.keys():
391+
value = row[column]
392+
if (column, value) in expanded_labels and value is not None:
393+
new_row[column] = {
394+
"value": value,
395+
"label": expanded_labels[(column, value)],
396+
}
397+
else:
398+
new_row[column] = value
399+
new_rows.append(new_row)
400+
rows = new_rows
401+
return rows, expanded_columns
402+
403+
338404
class TableInsertView(BaseView):
339405
name = "table-insert"
340406

@@ -1210,59 +1276,15 @@ async def table_view_data(
12101276
rows = list(results.rows)
12111277

12121278
# Expand labeled columns if requested
1213-
expanded_columns = []
1214-
# List of (fk_dict, label_column-or-None) pairs for that table
1215-
expandable_columns = []
1216-
for fk in await db.foreign_keys_for_table(table_name):
1217-
label_column = await db.label_column_for_table(fk["other_table"])
1218-
expandable_columns.append((fk, label_column))
1219-
1220-
columns_to_expand = None
1221-
try:
1222-
all_labels = value_as_boolean(request.args.get("_labels", ""))
1223-
except ValueError:
1224-
all_labels = default_labels
1225-
# Check for explicit _label=
1226-
if "_label" in request.args:
1227-
columns_to_expand = request.args.getlist("_label")
1228-
if columns_to_expand is None and all_labels:
1229-
# expand all columns with foreign keys
1230-
columns_to_expand = [fk["column"] for fk, _ in expandable_columns]
1231-
1232-
if columns_to_expand:
1233-
expanded_labels = {}
1234-
for fk, _ in expandable_columns:
1235-
column = fk["column"]
1236-
if column not in columns_to_expand:
1237-
continue
1238-
if column not in columns:
1239-
continue
1240-
expanded_columns.append(column)
1241-
# Gather the values
1242-
column_index = columns.index(column)
1243-
values = [row[column_index] for row in rows]
1244-
# Expand them
1245-
expanded_labels.update(
1246-
await datasette.expand_foreign_keys(
1247-
request.actor, database_name, table_name, column, values
1248-
)
1249-
)
1250-
if expanded_labels:
1251-
# Rewrite the rows
1252-
new_rows = []
1253-
for row in rows:
1254-
new_row = CustomRow(columns)
1255-
for column in row.keys():
1256-
value = row[column]
1257-
if (column, value) in expanded_labels and value is not None:
1258-
new_row[column] = {
1259-
"value": value,
1260-
"label": expanded_labels[(column, value)],
1261-
}
1262-
else:
1263-
new_row[column] = value
1264-
new_rows.append(new_row)
1265-
rows = new_rows
1279+
rows, expanded_columns = await expand_labels(
1280+
datasette,
1281+
db,
1282+
request,
1283+
table_name,
1284+
columns,
1285+
rows,
1286+
default_labels,
1287+
)
12661288

12671289
_next = request.args.get("_next")
12681290

tests/test_table_html.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,38 @@ async def test_table_html_foreign_key_links(ds_client):
629629
]
630630

631631

632+
@pytest.mark.asyncio
633+
async def test_row_html_foreign_key_links(ds_client):
634+
response = await ds_client.get("/fixtures/foreign_key_references/1")
635+
assert response.status_code == 200
636+
table = Soup(response.text, "html.parser").find("table")
637+
actual = [[str(td) for td in tr.select("td")] for tr in table.select("tbody tr")]
638+
assert actual == [
639+
[
640+
'<td class="col-pk type-str">1</td>',
641+
'<td class="col-foreign_key_with_label type-str"><a href="/fixtures/simple_primary_key/1">hello</a>\xa0<em>1</em></td>',
642+
'<td class="col-foreign_key_with_blank_label type-str"><a href="/fixtures/simple_primary_key/3">-</a>\xa0<em>3</em></td>',
643+
'<td class="col-foreign_key_with_no_label type-str"><a href="/fixtures/primary_key_multiple_columns/1">1</a></td>',
644+
'<td class="col-foreign_key_compound_pk1 type-str">a</td>',
645+
'<td class="col-foreign_key_compound_pk2 type-str">b</td>',
646+
],
647+
]
648+
response = await ds_client.get("/fixtures/foreign_key_references/2")
649+
assert response.status_code == 200
650+
table = Soup(response.text, "html.parser").find("table")
651+
actual = [[str(td) for td in tr.select("td")] for tr in table.select("tbody tr")]
652+
assert actual == [
653+
[
654+
'<td class="col-pk type-str">2</td>',
655+
'<td class="col-foreign_key_with_label type-none">\xa0</td>',
656+
'<td class="col-foreign_key_with_blank_label type-none">\xa0</td>',
657+
'<td class="col-foreign_key_with_no_label type-none">\xa0</td>',
658+
'<td class="col-foreign_key_compound_pk1 type-none">\xa0</td>',
659+
'<td class="col-foreign_key_compound_pk2 type-none">\xa0</td>',
660+
],
661+
]
662+
663+
632664
@pytest.mark.asyncio
633665
async def test_table_html_foreign_key_facets(ds_client):
634666
response = await ds_client.get(

0 commit comments

Comments
 (0)