diff --git a/datasette/app.py b/datasette/app.py index 1a20dbd0..3793cd55 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -699,9 +699,7 @@ class Datasette: if hook: for ct in hook: if ct.name in self._column_types: - raise StartupError( - f"Duplicate column type name: {ct.name}" - ) + raise StartupError(f"Duplicate column type name: {ct.name}") self._column_types[ct.name] = ct for hook in pm.hook.prepare_jinja2_environment( @@ -977,15 +975,16 @@ class Datasette: logging.warning( "column_types config references unknown type %r " "for %s.%s.%s", - col_type, db_name, table_name, col_name, + col_type, + db_name, + table_name, + col_name, ) await self.set_column_type( db_name, table_name, col_name, col_type, config ) - async def get_column_type( - self, database: str, resource: str, column: str - ) -> tuple: + async def get_column_type(self, database: str, resource: str, column: str) -> tuple: """ Return (column_type_name, config_dict) for a specific column, or (None, None) if no column type is assigned. @@ -1001,9 +1000,7 @@ class Datasette: ct, config = rows[0] return (ct, json.loads(config) if config else None) - async def get_column_types( - self, database: str, resource: str - ) -> dict: + async def get_column_types(self, database: str, resource: str) -> dict: """ Return {column_name: (column_type_name, config_dict_or_None)} for all columns with assigned types on the given resource. @@ -1019,16 +1016,25 @@ class Datasette: } async def set_column_type( - self, database: str, resource: str, column: str, - column_type: str, config: dict = None + self, + database: str, + resource: str, + column: str, + column_type: str, + config: dict = None, ) -> None: """Assign a column type. Overwrites any existing assignment.""" await self.get_internal_database().execute_write( """INSERT OR REPLACE INTO column_types (database_name, resource_name, column_name, column_type, config) VALUES (?, ?, ?, ?, ?)""", - [database, resource, column, column_type, - json.dumps(config) if config else None], + [ + database, + resource, + column, + column_type, + json.dumps(config) if config else None, + ], ) async def remove_column_type( diff --git a/datasette/hookspecs.py b/datasette/hookspecs.py index ec779659..86cd529e 100644 --- a/datasette/hookspecs.py +++ b/datasette/hookspecs.py @@ -56,8 +56,16 @@ def publish_subcommand(publish): @hookspec def render_cell( - row, value, column, table, pks, database, datasette, request, - column_type, column_type_config + row, + value, + column, + table, + pks, + database, + datasette, + request, + column_type, + column_type_config, ): """Customize rendering of HTML table cell values""" diff --git a/datasette/views/row.py b/datasette/views/row.py index 0702368d..d1713d4d 100644 --- a/datasette/views/row.py +++ b/datasette/views/row.py @@ -193,18 +193,27 @@ class RowView(DataView): ct_class = self.ds.get_column_type_class(ct_name) if ct_class: candidate = await ct_class.render_cell( - value=value, column=column, table=table, - database=database, datasette=self.ds, - request=request, config=ct_config, + value=value, + column=column, + table=table, + database=database, + datasette=self.ds, + request=request, + config=ct_config, ) if candidate is not None: plugin_display_value = candidate if plugin_display_value is None: for candidate in pm.hook.render_cell( - row=row, value=value, column=column, - table=table, pks=resolved.pks, - database=database, datasette=self.ds, - request=request, column_type=ct_name, + row=row, + value=value, + column=column, + table=table, + pks=resolved.pks, + database=database, + datasette=self.ds, + request=request, + column_type=ct_name, column_type_config=ct_config, ): candidate = await await_me_maybe(candidate) @@ -366,6 +375,7 @@ class RowUpdateView(BaseView): # Validate column types from datasette.views.table import _validate_column_types + ct_errors = await _validate_column_types( self.ds, resolved.db.name, resolved.table, [update] ) diff --git a/docs/internals.rst b/docs/internals.rst index f1064b8b..e9c6454e 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -944,9 +944,7 @@ Returns a dictionary mapping column names to ``(column_type_name, config)`` tupl .. code-block:: python - ct_map = await datasette.get_column_types( - "mydb", "mytable" - ) + ct_map = await datasette.get_column_types("mydb", "mytable") # {"email_col": ("email", None), "site": ("url", None)} .. _datasette_set_column_type: @@ -970,8 +968,11 @@ Assigns a column type to a column. Overwrites any existing assignment for that c .. code-block:: python await datasette.set_column_type( - "mydb", "mytable", "location", "point", - config={"srid": 4326} + "mydb", + "mytable", + "location", + "point", + config={"srid": 4326}, ) .. _datasette_remove_column_type: diff --git a/docs/plugin_hooks.rst b/docs/plugin_hooks.rst index b25403b3..052c17b0 100644 --- a/docs/plugin_hooks.rst +++ b/docs/plugin_hooks.rst @@ -1013,8 +1013,14 @@ Return a list of :ref:`ColumnType ` instances to register custom c class ColorColumnType(ColumnType): async def render_cell( - self, value, column, table, database, - datasette, request, config + self, + value, + column, + table, + database, + datasette, + request, + config, ): if value: return markupsafe.Markup(