mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
parent
583b22aa28
commit
9c77e6e355
3 changed files with 63 additions and 43 deletions
|
|
@ -219,13 +219,14 @@ class TableView(RowTableShared):
|
|||
# it can still be queried using ?_col__exact=blah
|
||||
special_args = {}
|
||||
special_args_lists = {}
|
||||
other_args = {}
|
||||
other_args = []
|
||||
for key, value in args.items():
|
||||
if key.startswith("_") and "__" not in key:
|
||||
special_args[key] = value[0]
|
||||
special_args_lists[key] = value
|
||||
else:
|
||||
other_args[key] = value[0]
|
||||
for v in value:
|
||||
other_args.append((key, v))
|
||||
|
||||
# Handle ?_filter_column and redirect, if present
|
||||
redirect_params = filters_should_redirect(special_args)
|
||||
|
|
@ -253,7 +254,7 @@ class TableView(RowTableShared):
|
|||
|
||||
table_metadata = self.ds.table_metadata(database, table)
|
||||
units = table_metadata.get("units", {})
|
||||
filters = Filters(sorted(other_args.items()), units, ureg)
|
||||
filters = Filters(sorted(other_args), units, ureg)
|
||||
where_clauses, params = filters.build_where_clauses(table)
|
||||
|
||||
extra_wheres_for_ui = []
|
||||
|
|
@ -521,7 +522,7 @@ class TableView(RowTableShared):
|
|||
database, table, column, values
|
||||
))
|
||||
for row in facet_rows:
|
||||
selected = str(other_args.get(column)) == str(row["value"])
|
||||
selected = (column, str(row["value"])) in other_args
|
||||
if selected:
|
||||
toggle_path = path_with_removed_args(
|
||||
request, {column: str(row["value"])}
|
||||
|
|
|
|||
|
|
@ -903,6 +903,16 @@ def test_table_filter_queries(app_client, path, expected_rows):
|
|||
assert expected_rows == response.json['rows']
|
||||
|
||||
|
||||
def test_table_filter_queries_multiple_of_same_type(app_client):
|
||||
response = app_client.get(
|
||||
"/fixtures/simple_primary_key.json?content__not=world&content__not=hello"
|
||||
)
|
||||
assert [
|
||||
['3', ''],
|
||||
['4', 'RENDER_CELL_DEMO']
|
||||
] == response.json['rows']
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not detect_json1(),
|
||||
reason="Requires the SQLite json1 module"
|
||||
|
|
|
|||
|
|
@ -4,88 +4,97 @@ import pytest
|
|||
|
||||
@pytest.mark.parametrize('args,expected_where,expected_params', [
|
||||
(
|
||||
{
|
||||
'name_english__contains': 'foo',
|
||||
},
|
||||
(
|
||||
('name_english__contains', 'foo'),
|
||||
),
|
||||
['"name_english" like :p0'],
|
||||
['%foo%']
|
||||
),
|
||||
(
|
||||
{
|
||||
'foo': 'bar',
|
||||
'bar__contains': 'baz',
|
||||
},
|
||||
(
|
||||
('foo', 'bar'),
|
||||
('bar__contains', 'baz'),
|
||||
),
|
||||
['"bar" like :p0', '"foo" = :p1'],
|
||||
['%baz%', 'bar']
|
||||
),
|
||||
(
|
||||
{
|
||||
'foo__startswith': 'bar',
|
||||
'bar__endswith': 'baz',
|
||||
},
|
||||
(
|
||||
('foo__startswith', 'bar'),
|
||||
('bar__endswith', 'baz'),
|
||||
),
|
||||
['"bar" like :p0', '"foo" like :p1'],
|
||||
['%baz', 'bar%']
|
||||
),
|
||||
(
|
||||
{
|
||||
'foo__lt': '1',
|
||||
'bar__gt': '2',
|
||||
'baz__gte': '3',
|
||||
'bax__lte': '4',
|
||||
},
|
||||
(
|
||||
('foo__lt', '1'),
|
||||
('bar__gt', '2'),
|
||||
('baz__gte', '3'),
|
||||
('bax__lte', '4'),
|
||||
),
|
||||
['"bar" > :p0', '"bax" <= :p1', '"baz" >= :p2', '"foo" < :p3'],
|
||||
[2, 4, 3, 1]
|
||||
),
|
||||
(
|
||||
{
|
||||
'foo__like': '2%2',
|
||||
'zax__glob': '3*',
|
||||
},
|
||||
(
|
||||
('foo__like', '2%2'),
|
||||
('zax__glob', '3*'),
|
||||
),
|
||||
['"foo" like :p0', '"zax" glob :p1'],
|
||||
['2%2', '3*']
|
||||
),
|
||||
# Multiple like arguments:
|
||||
(
|
||||
{
|
||||
'foo__isnull': '1',
|
||||
'baz__isnull': '1',
|
||||
'bar__gt': '10'
|
||||
},
|
||||
(
|
||||
('foo__like', '2%2'),
|
||||
('foo__like', '3%3'),
|
||||
),
|
||||
['"foo" like :p0', '"foo" like :p1'],
|
||||
['2%2', '3%3']
|
||||
),
|
||||
(
|
||||
(
|
||||
('foo__isnull', '1'),
|
||||
('baz__isnull', '1'),
|
||||
('bar__gt', '10'),
|
||||
),
|
||||
['"bar" > :p0', '"baz" is null', '"foo" is null'],
|
||||
[10]
|
||||
),
|
||||
(
|
||||
{
|
||||
'foo__in': '1,2,3',
|
||||
},
|
||||
(
|
||||
('foo__in', '1,2,3'),
|
||||
),
|
||||
['foo in (:p0, :p1, :p2)'],
|
||||
["1", "2", "3"]
|
||||
),
|
||||
# date
|
||||
(
|
||||
{
|
||||
"foo__date": "1988-01-01",
|
||||
},
|
||||
(
|
||||
("foo__date", "1988-01-01"),
|
||||
),
|
||||
["date(foo) = :p0"],
|
||||
["1988-01-01"]
|
||||
),
|
||||
# JSON array variants of __in (useful for unexpected characters)
|
||||
(
|
||||
{
|
||||
'foo__in': '[1,2,3]',
|
||||
},
|
||||
(
|
||||
('foo__in', '[1,2,3]'),
|
||||
),
|
||||
['foo in (:p0, :p1, :p2)'],
|
||||
[1, 2, 3]
|
||||
),
|
||||
(
|
||||
{
|
||||
'foo__in': '["dog,cat", "cat[dog]"]',
|
||||
},
|
||||
(
|
||||
('foo__in', '["dog,cat", "cat[dog]"]'),
|
||||
),
|
||||
['foo in (:p0, :p1)'],
|
||||
["dog,cat", "cat[dog]"]
|
||||
),
|
||||
])
|
||||
def test_build_where(args, expected_where, expected_params):
|
||||
f = Filters(sorted(args.items()))
|
||||
f = Filters(sorted(args))
|
||||
sql_bits, actual_params = f.build_where_clauses("table")
|
||||
assert expected_where == sql_bits
|
||||
assert {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue