Link foreign keys which don't have labels

This renders unlabeled FKs as simple links. I can't see why this would
cause any major problems.

Also includes bonus fixes for two minor issues:

* In foreign key link hrefs the primary key was escaped using HTML
  escaping rather than URL escaping. This broke some non-integer PKs.
* Print tracebacks to console when handling 500 errors.
pull/205/head^2
Russ Garrett 2018-04-14 14:17:20 +01:00 zatwierdzone przez Simon Willison
rodzic d72201e883
commit f2b940d602
1 zmienionych plików z 18 dodań i 6 usunięć

Wyświetl plik

@ -17,6 +17,7 @@ import jinja2
import hashlib
import time
import pint
import traceback
from .utils import (
Filters,
CustomJSONEncoder,
@ -479,13 +480,15 @@ class RowTableShared(BaseView):
pks = table_info.get('primary_keys') or []
# Prefetch foreign key resolutions for later expansion:
expanded = {}
fks = {}
labeled_fks = {}
if table_info and expand_foreign_keys:
foreign_keys = table_info['foreign_keys']['outgoing']
for fk in foreign_keys:
label_column = tables.get(fk['other_table'], {}).get('label_column')
if not label_column:
# We only link cells to other tables with label columns defined
# No label for this FK
fks[fk['column']] = fk['other_table']
continue
ids_to_lookup = set([row[fk['column']] for row in rows])
sql = 'select "{other_column}", "{label_column}" from {other_table} where "{other_column}" in ({placeholders})'.format(
@ -501,7 +504,7 @@ class RowTableShared(BaseView):
pass
else:
for id, value in results:
expanded[(fk['column'], id)] = (fk['other_table'], value)
labeled_fks[(fk['column'], id)] = (fk['other_table'], value)
cell_rows = []
for row in rows:
@ -521,16 +524,24 @@ class RowTableShared(BaseView):
})
for value, column_dict in zip(row, columns):
column = column_dict['name']
if (column, value) in expanded:
other_table, label = expanded[(column, value)]
if (column, value) in labeled_fks:
other_table, label = labeled_fks[(column, value)]
display_value = jinja2.Markup(
'<a href="/{database}/{table}/{id}">{label}</a>&nbsp;<em>{id}</em>'.format(
'<a href="/{database}/{table}/{link_id}">{label}</a>&nbsp;<em>{id}</em>'.format(
database=database,
table=urllib.parse.quote_plus(other_table),
link_id=urllib.parse.quote_plus(str(value)),
id=str(jinja2.escape(value)),
label=str(jinja2.escape(label)),
)
)
elif column in fks:
display_value = jinja2.Markup(
'<a href="/{database}/{table}/{link_id}">{id}</a>'.format(
database=database,
table=urllib.parse.quote_plus(fks[column]),
link_id=urllib.parse.quote_plus(str(value)),
id=str(jinja2.escape(value))))
elif value is None:
display_value = jinja2.Markup('&nbsp;')
elif is_url(str(value).strip()):
@ -1244,6 +1255,7 @@ class Datasette:
status = 500
info = {}
message = str(exception)
traceback.print_exc()
templates = ['500.html']
if status != 500:
templates = ['{}.html'.format(status)] + templates