diff --git a/datasette/app.py b/datasette/app.py
index 72ff5264..67ee207f 100644
--- a/datasette/app.py
+++ b/datasette/app.py
@@ -773,8 +773,17 @@ class TableView(RowTableShared):
# Almost certainly hit the timeout
pass
- # human_filter_description combines filters AND search, if provided
- human_description = filters.human_description(extra=search_description)
+ # human_description_en combines filters AND search, if provided
+ human_description_en = filters.human_description_en(extra=search_description)
+
+ if sort or sort_desc:
+ sorted_by = 'sorted by {}{}'.format(
+ (sort or sort_desc),
+ ' descending' if sort_desc else '',
+ )
+ human_description_en = ' '.join([
+ b for b in [human_description_en, sorted_by] if b
+ ])
async def extra_template():
display_columns, display_rows = await self.display_columns_and_rows(
@@ -786,7 +795,6 @@ class TableView(RowTableShared):
self.ds.update_with_inherited_metadata(metadata)
return {
'database_hash': hash,
- 'human_filter_description': human_description,
'supports_search': bool(fts_table),
'search': search or '',
'use_rowid': use_rowid,
@@ -808,6 +816,7 @@ class TableView(RowTableShared):
'is_view': is_view,
'view_definition': view_definition,
'table_definition': table_definition,
+ 'human_description_en': human_description_en,
'rows': rows[:self.page_size],
'truncated': truncated,
'table_rows': table_rows,
diff --git a/datasette/templates/table.html b/datasette/templates/table.html
index 546e852f..91cf70f0 100644
--- a/datasette/templates/table.html
+++ b/datasette/templates/table.html
@@ -1,7 +1,7 @@
{% extends "base.html" %}
{% block title %}{{ database }}: {{ table }}: {% if filtered_table_rows or filtered_table_rows == 0 %}{{ "{:,}".format(filtered_table_rows) }} row{% if filtered_table_rows == 1 %}{% else %}s{% endif %}{% endif %}
- {% if human_filter_description %}where {{ human_filter_description }}{% endif %}{% endblock %}
+ {% if human_description_en %}where {{ human_description_en }}{% endif %}{% endblock %}
{% block extra_head %}
{{ super() }}
@@ -23,9 +23,9 @@
{% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %}
-{% if filtered_table_rows or human_filter_description %}
+{% if filtered_table_rows or human_description_en %}
{% if filtered_table_rows or filtered_table_rows == 0 %}{{ "{:,}".format(filtered_table_rows) }} row{% if filtered_table_rows == 1 %}{% else %}s{% endif %}{% endif %}
- {% if human_filter_description %}where {{ human_filter_description }}{% endif %}
+ {% if human_description_en %}where {{ human_description_en }}{% endif %}
{% endif %}
diff --git a/datasette/utils.py b/datasette/utils.py
index b7798bf4..4a2e0ed5 100644
--- a/datasette/utils.py
+++ b/datasette/utils.py
@@ -460,7 +460,7 @@ class Filters:
for filter in self._filters:
yield filter.key, filter.display, filter.no_argument
- def human_description(self, extra=None):
+ def human_description_en(self, extra=None):
bits = []
if extra:
bits.append(extra)
diff --git a/tests/test_api.py b/tests/test_api.py
index acdd5e71..98894c33 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -356,18 +356,19 @@ def test_paginate_compound_keys_with_extra_filters(app_client):
assert expected == [f['content'] for f in fetched]
-@pytest.mark.parametrize('query_string,sort_key', [
- ('_sort=sortable', lambda row: row['sortable']),
- ('_sort_desc=sortable', lambda row: -row['sortable']),
+@pytest.mark.parametrize('query_string,sort_key,human_description_en', [
+ ('_sort=sortable', lambda row: row['sortable'], 'sorted by sortable'),
+ ('_sort_desc=sortable', lambda row: -row['sortable'], 'sorted by sortable descending'),
])
-def test_sortable(app_client, query_string, sort_key):
- path = '/test_tables/sortable.jsono?{}'.format(query_string)
+def test_sortable(app_client, query_string, sort_key, human_description_en):
+ path = '/test_tables/sortable.json?_shape=objects&{}'.format(query_string)
fetched = []
page = 0
while path:
page += 1
assert page < 100
response = app_client.get(path, gather_request=False)
+ assert human_description_en == response.json['human_description_en']
fetched.extend(response.json['rows'])
path = response.json['next_url']
assert 5 == page
@@ -380,6 +381,25 @@ def test_sortable(app_client, query_string, sort_key):
]
+def test_sortable_and_filtered(app_client):
+ path = (
+ '/test_tables/sortable.json'
+ '?content__contains=d&_sort_desc=sortable&_shape=objects'
+ )
+ response = app_client.get(path, gather_request=False)
+ fetched = response.json['rows']
+ expected = [
+ row for row in generate_sortable_rows(201)
+ if 'd' in row['content']
+ ]
+ expected.sort(key=lambda row: -row['sortable'])
+ assert [
+ r['content'] for r in expected
+ ] == [
+ r['content'] for r in fetched
+ ]
+
+
@pytest.mark.parametrize('path,expected_rows', [
('/test_tables/simple_primary_key.json?content=hello', [
['1', 'hello'],