mirror of
https://github.com/simonw/datasette.git
synced 2026-06-06 00:56:57 +02:00
Respect metadata-defined facet ordering in sorted_facet_results (#2648)
* Preserve metadata-defined facet ordering on table pages When facets are explicitly defined in table metadata/config, they now appear in the order specified in the configuration rather than being sorted by result count. Request-added facets still appear after metadata-defined facets, sorted by count as before. * Document metadata-defined facet ordering behavior * Apply black formatting https://claude.ai/code/session_01PbSHtjsUpNk3Fx7xjvVqDb
This commit is contained in:
parent
c96dc5ce26
commit
24d801b7f7
3 changed files with 71 additions and 9 deletions
|
|
@ -1580,11 +1580,35 @@ async def table_view_data(
|
|||
]
|
||||
|
||||
async def extra_sorted_facet_results(extra_facet_results):
|
||||
return sorted(
|
||||
extra_facet_results["results"].values(),
|
||||
key=lambda f: (len(f["results"]), f["name"]),
|
||||
reverse=True,
|
||||
)
|
||||
facet_configs = table_metadata.get("facets", [])
|
||||
if facet_configs:
|
||||
# Build ordered list of facet names from metadata config
|
||||
metadata_facet_names = []
|
||||
for fc in facet_configs:
|
||||
if isinstance(fc, str):
|
||||
metadata_facet_names.append(fc)
|
||||
elif isinstance(fc, dict):
|
||||
metadata_facet_names.append(list(fc.values())[0])
|
||||
metadata_order = {name: i for i, name in enumerate(metadata_facet_names)}
|
||||
metadata_facets = []
|
||||
request_facets = []
|
||||
for f in extra_facet_results["results"].values():
|
||||
if f["name"] in metadata_order:
|
||||
metadata_facets.append(f)
|
||||
else:
|
||||
request_facets.append(f)
|
||||
metadata_facets.sort(key=lambda f: metadata_order[f["name"]])
|
||||
request_facets.sort(
|
||||
key=lambda f: (len(f["results"]), f["name"]),
|
||||
reverse=True,
|
||||
)
|
||||
return metadata_facets + request_facets
|
||||
else:
|
||||
return sorted(
|
||||
extra_facet_results["results"].values(),
|
||||
key=lambda f: (len(f["results"]), f["name"]),
|
||||
reverse=True,
|
||||
)
|
||||
|
||||
async def extra_table_definition():
|
||||
return await db.get_table_definition(table_name)
|
||||
|
|
|
|||
|
|
@ -153,6 +153,8 @@ Here's an example that turns on faceting by default for the ``qLegalStatus`` col
|
|||
|
||||
Facets defined in this way will always be shown in the interface and returned in the API, regardless of the ``_facet`` arguments passed to the view.
|
||||
|
||||
Facets defined in metadata will be displayed in the order they are listed in the configuration. Any additional facets added via query string parameters (e.g. ``?_facet=column_name``) will appear after the metadata-defined facets, sorted by the number of unique values.
|
||||
|
||||
You can specify :ref:`array <facet_by_json_array>` or :ref:`date <facet_by_date>` facets in metadata using JSON objects with a single key of ``array`` or ``date`` and a value specifying the column, like this:
|
||||
|
||||
.. [[[cog
|
||||
|
|
|
|||
|
|
@ -623,12 +623,48 @@ def test_other_types_of_facet_in_metadata():
|
|||
}
|
||||
) as client:
|
||||
response = client.get("/fixtures/facetable")
|
||||
for fragment in (
|
||||
"<strong>created (date)\n",
|
||||
"<strong>tags (array)\n",
|
||||
fragments = (
|
||||
"<strong>state\n",
|
||||
):
|
||||
"<strong>tags (array)\n",
|
||||
"<strong>created (date)\n",
|
||||
)
|
||||
for fragment in fragments:
|
||||
assert fragment in response.text
|
||||
# Verify they appear in the metadata-defined order
|
||||
positions = [response.text.index(f) for f in fragments]
|
||||
assert positions == sorted(
|
||||
positions
|
||||
), "Facets should appear in metadata-defined order"
|
||||
|
||||
|
||||
def test_metadata_facet_ordering():
|
||||
with make_app_client(
|
||||
metadata={
|
||||
"databases": {
|
||||
"fixtures": {
|
||||
"tables": {
|
||||
"facetable": {
|
||||
"facets": ["state", {"array": "tags"}, {"date": "created"}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
) as client:
|
||||
# JSON response should have facets in the metadata-defined order
|
||||
response = client.get("/fixtures/facetable.json?_extra=sorted_facet_results")
|
||||
data = response.json
|
||||
facet_names = [f["name"] for f in data["sorted_facet_results"]]
|
||||
assert facet_names == ["state", "tags", "created"]
|
||||
|
||||
# With an additional request-based facet, metadata facets come first
|
||||
# in their defined order, followed by request-based facets
|
||||
response2 = client.get(
|
||||
"/fixtures/facetable.json?_extra=sorted_facet_results&_facet=_city_id"
|
||||
)
|
||||
data2 = response2.json
|
||||
facet_names2 = [f["name"] for f in data2["sorted_facet_results"]]
|
||||
assert facet_names2 == ["state", "tags", "created", "_city_id"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue