?_filter_column=col&_filter_op=op&_filter_value=value redirect

Part of implementing the filters UI (refs #86) - the following:

    /trees/Trees?_filter_column=SiteOrder&_filter_op=gt&_filter_value=2

Now redirects to this;

    /trees/Trees?SiteOrder__gt=2
pull/104/head
Simon Willison 2017-11-19 12:25:29 -08:00
rodzic ddc808f387
commit 386fb11d42
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: FBB38AFE227189DB
3 zmienionych plików z 53 dodań i 6 usunięć

Wyświetl plik

@ -57,7 +57,7 @@ class BaseView(HTTPMethodView):
return r
def redirect(self, request, path):
if request.query_string:
if request.query_string and '?' not in path:
path = '{}?{}'.format(
path, request.query_string
)
@ -182,9 +182,13 @@ class BaseView(HTTPMethodView):
template = self.template
status_code = 200
try:
data, extra_template_data = await self.data(
response_or_template_contexts = await self.data(
request, name, hash, **kwargs
)
if isinstance(response_or_template_contexts, response.HTTPResponse):
return response_or_template_contexts
else:
data, extra_template_data = response_or_template_contexts
except (sqlite3.OperationalError, InvalidSql) as e:
data = {
'ok': False,
@ -422,6 +426,18 @@ class TableView(BaseView):
else:
other_args[key] = value[0]
# Handle ?_filter_column and redirect, if present
if '_filter_column' in special_args:
filter_column = special_args['_filter_column']
filter_op = special_args.get('_filter_op') or ''
filter_value = special_args.get('_filter_value') or ''
return self.redirect(request, path_with_added_args(request, {
'{}__{}'.format(filter_column, filter_op): filter_value,
'_filter_column': None,
'_filter_op': None,
'_filter_value': None,
}))
if other_args:
where_clauses, params = build_where_clauses(other_args)
else:
@ -433,7 +449,7 @@ class TableView(BaseView):
fts_sql = detect_fts_sql(table)
fts_rows = list(await self.execute(name, fts_sql))
if fts_rows:
fts_table=fts_rows[0][0]
fts_table = fts_rows[0][0]
search = special_args.get('_search')
if search and fts_table:

Wyświetl plik

@ -120,9 +120,17 @@ def validate_sql_select(sql):
def path_with_added_args(request, args):
current = request.raw_args.copy()
current.update(args)
return request.path + '?' + urllib.parse.urlencode(current)
current = {
key: value
for key, value in request.raw_args.items()
if key not in args
}
current.update({
key: value
for key, value in args.items()
if value is not None
})
return request.path + '?' + urllib.parse.urlencode(sorted(current.items()))
def path_with_ext(request, ext):

Wyświetl plik

@ -4,6 +4,7 @@ import pytest
import sqlite3
import tempfile
import time
import urllib.parse
@pytest.fixture(scope='module')
@ -227,6 +228,28 @@ def test_row(app_client):
assert [{'pk': '1', 'content': 'hello'}] == response.json['rows']
def test_add_filter_redirects(app_client):
filter_args = urllib.parse.urlencode({
'_filter_column': 'content',
'_filter_op': 'startswith',
'_filter_value': 'x'
})
# First we need to resolve the correct path before testing more redirects
path_base = app_client.get(
'/test_tables/simple_primary_key', allow_redirects=False, gather_request=False
).headers['Location']
path = path_base + '?' + filter_args
response = app_client.get(path, allow_redirects=False, gather_request=False)
assert response.status == 302
assert response.headers['Location'].endswith('?content__startswith=x')
# Adding a redirect to an existing querystring:
path = path_base + '?foo=bar&' + filter_args
response = app_client.get(path, allow_redirects=False, gather_request=False)
assert response.status == 302
assert response.headers['Location'].endswith('?content__startswith=x&foo=bar')
TABLES = '''
CREATE TABLE simple_primary_key (
pk varchar(30) primary key,