Started implementing ?name__contains=X filters

So far we support __contains=, __startswith=, __endswith= and __exact=

Refs #23
This commit is contained in:
Simon Willison 2017-10-24 17:06:23 -07:00
commit 1ae8ea0f03
2 changed files with 59 additions and 1 deletions

41
app.py
View file

@ -183,7 +183,15 @@ class TableView(BaseView):
def data(self, request, name, hash, table):
conn = get_conn(name)
rows = conn.execute('select * from {} limit 20'.format(table))
if request.args:
where_clause, params = build_where_clause(request.args)
sql = 'select * from "{}" where {} limit 50'.format(
table, where_clause
)
else:
sql = 'select * from "{}" limit 50'.format(table)
params = []
rows = conn.execute(sql, params)
columns = [r[0] for r in rows.description]
pks = pks_for_table(conn, table)
rows = list(rows)
@ -294,6 +302,37 @@ def path_from_row_pks(row, pks):
return ','.join(bits)
def build_where_clause(args):
sql_bits = []
for key, values in args.items():
if '__' in key:
column, lookup = key.rsplit('__', 1)
else:
column = key
lookup = 'exact'
template = {
'exact': '"{}" = ?',
'contains': '"{}" like ?',
'endswith': '"{}" like ?',
'startswith': '"{}" like ?',
}[lookup]
value = values[0]
value_convert = {
'exact': lambda s: s,
'contains': lambda s: '%{}%'.format(s),
'endswith': lambda s: '%{}'.format(s),
'startswith': lambda s: '{}%'.format(s),
}[lookup]
converted = value_convert(value)
sql_bits.append(
(template.format(column), converted)
)
sql_bits.sort(key=lambda p: p[0])
where_clause = ' and '.join(p[0] for p in sql_bits)
params = [p[1] for p in sql_bits]
return where_clause, params
class CustomJSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, sqlite3.Row):