kopia lustrzana https://github.com/simonw/datasette
Expand labels in row view as well
rodzic
72f8ac680a
commit
d903e48b43
|
@ -11,7 +11,7 @@ from datasette.utils import (
|
|||
from datasette.plugins import pm
|
||||
import json
|
||||
import sqlite_utils
|
||||
from .table import display_columns_and_rows
|
||||
from .table import display_columns_and_rows, expand_labels
|
||||
|
||||
|
||||
class RowView(DataView):
|
||||
|
@ -44,6 +44,11 @@ class RowView(DataView):
|
|||
if not rows:
|
||||
raise NotFound(f"Record not found: {pk_values}")
|
||||
|
||||
# Expand labeled columns if requested
|
||||
rows, _ = await expand_labels(
|
||||
self.ds, db, request, table, columns, rows, default_labels
|
||||
)
|
||||
|
||||
async def template_data():
|
||||
display_columns, display_rows = await display_columns_and_rows(
|
||||
self.ds,
|
||||
|
|
|
@ -335,6 +335,72 @@ async def display_columns_and_rows(
|
|||
return columns, cell_rows
|
||||
|
||||
|
||||
async def expand_labels(
|
||||
datasette,
|
||||
db,
|
||||
request,
|
||||
table_name,
|
||||
columns,
|
||||
rows,
|
||||
default_labels,
|
||||
):
|
||||
"""Expands labeled columns if requested"""
|
||||
expanded_columns = []
|
||||
# List of (fk_dict, label_column-or-None) pairs for that table
|
||||
expandable_columns = []
|
||||
for fk in await db.foreign_keys_for_table(table_name):
|
||||
label_column = await db.label_column_for_table(fk["other_table"])
|
||||
expandable_columns.append((fk, label_column))
|
||||
|
||||
columns_to_expand = None
|
||||
try:
|
||||
all_labels = value_as_boolean(request.args.get("_labels", ""))
|
||||
except ValueError:
|
||||
all_labels = default_labels
|
||||
# Check for explicit _label=
|
||||
if "_label" in request.args:
|
||||
columns_to_expand = request.args.getlist("_label")
|
||||
if columns_to_expand is None and all_labels:
|
||||
# expand all columns with foreign keys
|
||||
columns_to_expand = [fk["column"] for fk, _ in expandable_columns]
|
||||
|
||||
if columns_to_expand:
|
||||
expanded_labels = {}
|
||||
for fk, _ in expandable_columns:
|
||||
column = fk["column"]
|
||||
if column not in columns_to_expand:
|
||||
continue
|
||||
if column not in columns:
|
||||
continue
|
||||
expanded_columns.append(column)
|
||||
# Gather the values
|
||||
column_index = columns.index(column)
|
||||
values = [row[column_index] for row in rows]
|
||||
# Expand them
|
||||
expanded_labels.update(
|
||||
await datasette.expand_foreign_keys(
|
||||
request.actor, db.name, table_name, column, values
|
||||
)
|
||||
)
|
||||
if expanded_labels:
|
||||
# Rewrite the rows
|
||||
new_rows = []
|
||||
for row in rows:
|
||||
new_row = CustomRow(columns)
|
||||
for column in row.keys():
|
||||
value = row[column]
|
||||
if (column, value) in expanded_labels and value is not None:
|
||||
new_row[column] = {
|
||||
"value": value,
|
||||
"label": expanded_labels[(column, value)],
|
||||
}
|
||||
else:
|
||||
new_row[column] = value
|
||||
new_rows.append(new_row)
|
||||
rows = new_rows
|
||||
return rows, expanded_columns
|
||||
|
||||
|
||||
class TableInsertView(BaseView):
|
||||
name = "table-insert"
|
||||
|
||||
|
@ -1199,59 +1265,15 @@ async def table_view_data(
|
|||
rows = list(results.rows)
|
||||
|
||||
# Expand labeled columns if requested
|
||||
expanded_columns = []
|
||||
# List of (fk_dict, label_column-or-None) pairs for that table
|
||||
expandable_columns = []
|
||||
for fk in await db.foreign_keys_for_table(table_name):
|
||||
label_column = await db.label_column_for_table(fk["other_table"])
|
||||
expandable_columns.append((fk, label_column))
|
||||
|
||||
columns_to_expand = None
|
||||
try:
|
||||
all_labels = value_as_boolean(request.args.get("_labels", ""))
|
||||
except ValueError:
|
||||
all_labels = default_labels
|
||||
# Check for explicit _label=
|
||||
if "_label" in request.args:
|
||||
columns_to_expand = request.args.getlist("_label")
|
||||
if columns_to_expand is None and all_labels:
|
||||
# expand all columns with foreign keys
|
||||
columns_to_expand = [fk["column"] for fk, _ in expandable_columns]
|
||||
|
||||
if columns_to_expand:
|
||||
expanded_labels = {}
|
||||
for fk, _ in expandable_columns:
|
||||
column = fk["column"]
|
||||
if column not in columns_to_expand:
|
||||
continue
|
||||
if column not in columns:
|
||||
continue
|
||||
expanded_columns.append(column)
|
||||
# Gather the values
|
||||
column_index = columns.index(column)
|
||||
values = [row[column_index] for row in rows]
|
||||
# Expand them
|
||||
expanded_labels.update(
|
||||
await datasette.expand_foreign_keys(
|
||||
request.actor, database_name, table_name, column, values
|
||||
)
|
||||
)
|
||||
if expanded_labels:
|
||||
# Rewrite the rows
|
||||
new_rows = []
|
||||
for row in rows:
|
||||
new_row = CustomRow(columns)
|
||||
for column in row.keys():
|
||||
value = row[column]
|
||||
if (column, value) in expanded_labels and value is not None:
|
||||
new_row[column] = {
|
||||
"value": value,
|
||||
"label": expanded_labels[(column, value)],
|
||||
}
|
||||
else:
|
||||
new_row[column] = value
|
||||
new_rows.append(new_row)
|
||||
rows = new_rows
|
||||
rows, expanded_columns = await expand_labels(
|
||||
datasette,
|
||||
db,
|
||||
request,
|
||||
table_name,
|
||||
columns,
|
||||
rows,
|
||||
default_labels,
|
||||
)
|
||||
|
||||
_next = request.args.get("_next")
|
||||
|
||||
|
|
|
@ -632,6 +632,38 @@ async def test_table_html_foreign_key_links(ds_client):
|
|||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_row_html_foreign_key_links(ds_client):
|
||||
response = await ds_client.get("/fixtures/foreign_key_references/1")
|
||||
assert response.status_code == 200
|
||||
table = Soup(response.text, "html.parser").find("table")
|
||||
actual = [[str(td) for td in tr.select("td")] for tr in table.select("tbody tr")]
|
||||
assert actual == [
|
||||
[
|
||||
'<td class="col-pk type-str">1</td>',
|
||||
'<td class="col-foreign_key_with_label type-str"><a href="/fixtures/simple_primary_key/1">hello</a>\xa0<em>1</em></td>',
|
||||
'<td class="col-foreign_key_with_blank_label type-str"><a href="/fixtures/simple_primary_key/3">-</a>\xa0<em>3</em></td>',
|
||||
'<td class="col-foreign_key_with_no_label type-str"><a href="/fixtures/primary_key_multiple_columns/1">1</a></td>',
|
||||
'<td class="col-foreign_key_compound_pk1 type-str">a</td>',
|
||||
'<td class="col-foreign_key_compound_pk2 type-str">b</td>',
|
||||
],
|
||||
]
|
||||
response = await ds_client.get("/fixtures/foreign_key_references/2")
|
||||
assert response.status_code == 200
|
||||
table = Soup(response.text, "html.parser").find("table")
|
||||
actual = [[str(td) for td in tr.select("td")] for tr in table.select("tbody tr")]
|
||||
assert actual == [
|
||||
[
|
||||
'<td class="col-pk type-str">2</td>',
|
||||
'<td class="col-foreign_key_with_label type-none">\xa0</td>',
|
||||
'<td class="col-foreign_key_with_blank_label type-none">\xa0</td>',
|
||||
'<td class="col-foreign_key_with_no_label type-none">\xa0</td>',
|
||||
'<td class="col-foreign_key_compound_pk1 type-none">\xa0</td>',
|
||||
'<td class="col-foreign_key_compound_pk2 type-none">\xa0</td>',
|
||||
],
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_table_html_foreign_key_facets(ds_client):
|
||||
response = await ds_client.get(
|
||||
|
|
Ładowanie…
Reference in New Issue