mirror of
https://github.com/simonw/datasette.git
synced 2026-10-19 15:56:58 +02:00
Row JSON: drop truncated, render_cell is a single object
The default row shape no longer includes "truncated", since a single row lookup cannot be truncated, and ?_extra=render_cell returns one object to match "row". With a ?_shape= both behave as they do for tables. Refs #2612 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GaqG8H8ajwxizKXdbGrtve
This commit is contained in:
parent
28184edc52
commit
cb0159e625
5 changed files with 28 additions and 19 deletions
|
|
@ -58,7 +58,8 @@ def json_renderer(request, args, data, error, truncated=None, view_name=None):
|
|||
status_code = 400
|
||||
data.update(error_body(error, status_code))
|
||||
|
||||
if truncated is not None:
|
||||
# A single row lookup cannot be truncated
|
||||
if truncated is not None and not single_row:
|
||||
data["truncated"] = truncated
|
||||
if shape == "arrayfirst":
|
||||
# Rows can be dicts, sqlite3.Row or lists (from remove_infinites)
|
||||
|
|
@ -78,6 +79,10 @@ def json_renderer(request, args, data, error, truncated=None, view_name=None):
|
|||
("row", row) if key == "rows" else (key, value)
|
||||
for key, value in data.items()
|
||||
)
|
||||
# Likewise the render_cell extra becomes a single object
|
||||
if "render_cell" in data:
|
||||
cells = data["render_cell"]
|
||||
data["render_cell"] = cells[0] if cells else {}
|
||||
if shape == "object":
|
||||
shape_error = None
|
||||
if "primary_keys" not in data:
|
||||
|
|
|
|||
|
|
@ -648,12 +648,13 @@ class RenderCellExtra(Extra):
|
|||
ExtraScope.ROW: ExtraExample(
|
||||
value={
|
||||
"row": {"id": 4, "content": "RENDER_CELL_DEMO"},
|
||||
"render_cell": [{"content": "<strong>Custom rendered HTML</strong>"}],
|
||||
"render_cell": {"content": "<strong>Custom rendered HTML</strong>"},
|
||||
},
|
||||
note=(
|
||||
"The ``render_cell`` array has one item for the requested row. "
|
||||
"The object is keyed by column name. Only columns whose rendered "
|
||||
"value differs from the default are included."
|
||||
"The ``render_cell`` object is keyed by column name. Only columns "
|
||||
"whose rendered value differs from the default are included. If a "
|
||||
"``?_shape=`` is specified ``render_cell`` is instead a list with "
|
||||
"one item, matching the ``rows`` list."
|
||||
),
|
||||
),
|
||||
ExtraScope.QUERY: ExtraExample(
|
||||
|
|
|
|||
|
|
@ -960,7 +960,7 @@ The following extras are available for row JSON responses.
|
|||
``render_cell``
|
||||
Rendered HTML for each cell using the render_cell plugin hook (See the :ref:`render_cell() plugin hook <plugin_hook_render_cell>` documentation.)
|
||||
|
||||
The ``render_cell`` array has one item for the requested row. The object is keyed by column name. Only columns whose rendered value differs from the default are included.
|
||||
The ``render_cell`` object is keyed by column name. Only columns whose rendered value differs from the default are included. If a ``?_shape=`` is specified ``render_cell`` is instead a list with one item, matching the ``rows`` list.
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
|
|
@ -969,11 +969,9 @@ The following extras are available for row JSON responses.
|
|||
"id": 4,
|
||||
"content": "RENDER_CELL_DEMO"
|
||||
},
|
||||
"render_cell": [
|
||||
{
|
||||
"content": "<strong>Custom rendered HTML</strong>"
|
||||
}
|
||||
]
|
||||
"render_cell": {
|
||||
"content": "<strong>Custom rendered HTML</strong>"
|
||||
}
|
||||
}
|
||||
|
||||
``debug``
|
||||
|
|
|
|||
|
|
@ -369,6 +369,7 @@ async def test_row(ds_client):
|
|||
assert data["ok"] is True
|
||||
assert data["row"] == {"id": 1, "content": "hello"}
|
||||
assert "rows" not in data
|
||||
assert "truncated" not in data
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
@ -391,6 +392,7 @@ async def test_row_shape(ds_client, shape, expected):
|
|||
data = response.json()
|
||||
if shape in ("objects", "arrays"):
|
||||
assert "row" not in data
|
||||
assert data["truncated"] is False
|
||||
data = data["rows"]
|
||||
assert data == expected
|
||||
|
||||
|
|
@ -650,20 +652,23 @@ async def test_row_extra_render_cell():
|
|||
assert "render_cell" in data
|
||||
assert "row" in data
|
||||
|
||||
# render_cell should be a list with one row (since this is a row page)
|
||||
# render_cell is a single object to match "row"
|
||||
# Only columns modified by plugins are included (sparse output)
|
||||
render_cell = data["render_cell"]
|
||||
assert len(render_cell) == 1
|
||||
|
||||
# The row: id=1, name='Alice'
|
||||
# The 'name' column should be rendered by our plugin as <strong>Alice</strong>
|
||||
assert render_cell[0]["name"] == "<strong>Alice</strong>"
|
||||
# The 'id' column is not included since no plugin modified it
|
||||
assert "id" not in render_cell[0]
|
||||
assert data["render_cell"] == {"name": "<strong>Alice</strong>"}
|
||||
|
||||
# The regular row should still contain raw values
|
||||
assert data["row"] == {"id": 1, "name": "Alice"}
|
||||
|
||||
# With a ?_shape= render_cell is a list, matching "rows"
|
||||
response = await ds.client.get(
|
||||
"/test_row_render/test_render/1.json?_extra=render_cell&_shape=objects"
|
||||
)
|
||||
data = response.json()
|
||||
assert data["render_cell"] == [{"name": "<strong>Alice</strong>"}]
|
||||
assert data["rows"] == [{"id": 1, "name": "Alice"}]
|
||||
|
||||
finally:
|
||||
ds.pm.unregister(name="TestRenderCellPlugin")
|
||||
|
||||
|
|
|
|||
|
|
@ -748,7 +748,7 @@ async def test_row_endpoint_render_cell_with_column_types(ds_ct):
|
|||
response = await ds_ct.client.get("/data/posts/1.json?_extra=render_cell")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
rendered = data["render_cell"][0]
|
||||
rendered = data["render_cell"]
|
||||
assert "mailto:" in rendered["author_email"]
|
||||
assert "href" in rendered["website"]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue