From f2b940d6026677f6859d46a4f16fa402745d261d Mon Sep 17 00:00:00 2001 From: Russ Garrett Date: Sat, 14 Apr 2018 14:17:20 +0100 Subject: [PATCH] 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. --- datasette/app.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/datasette/app.py b/datasette/app.py index 7d58319b..5259e253 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -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( - '{label} {id}'.format( + '{label} {id}'.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( + '{id}'.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(' ') 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