Skip to content

Commit

Permalink
[#4556] datatables: support search filters
Browse files Browse the repository at this point in the history
  • Loading branch information
wardi committed Jan 1, 2019
1 parent 69c9811 commit 2b248f2
Showing 1 changed file with 30 additions and 11 deletions.
41 changes: 30 additions & 11 deletions ckanext/datatablesview/controller.py
Expand Up @@ -19,7 +19,6 @@ def ajax(self, resource_view_id):
limit = int(request.params['length'])
view_filters = resource_view.get(u'filters', {})
user_filters = text_type(request.params['filters'])
filters = merge_filters(view_filters, user_filters)

datastore_search = get_action(u'datastore_search')
unfiltered_response = datastore_search(None, {
Expand All @@ -31,6 +30,11 @@ def ajax(self, resource_view_id):
cols = [f['id'] for f in unfiltered_response['fields']]
if u'show_fields' in resource_view:
cols = [c for c in cols if c in resource_view['show_fields']]
filters, q = merge_filters_q(
view_filters, user_filters, search_text, {
f['id']: f['info']['view_filter']
for f in unfiltered_response['fields']
if f.get(u'info', {}).get(u'view_filter')})

sort_list = []
i = 0
Expand All @@ -45,7 +49,7 @@ def ajax(self, resource_view_id):
i += 1

response = datastore_search(None, {
u"q": search_text,
u"q": q,
u"resource_id": resource_view[u'resource_id'],
u"offset": offset,
u"limit": limit,
Expand All @@ -71,7 +75,6 @@ def filtered_download(self, resource_view_id):
search_text = text_type(params['search']['value'])
view_filters = resource_view.get(u'filters', {})
user_filters = text_type(params['filters'])
filters = merge_filters(view_filters, user_filters)

datastore_search = get_action(u'datastore_search')
unfiltered_response = datastore_search(None, {
Expand All @@ -83,6 +86,11 @@ def filtered_download(self, resource_view_id):
cols = [f['id'] for f in unfiltered_response['fields']]
if u'show_fields' in resource_view:
cols = [c for c in cols if c in resource_view['show_fields']]
filters, q = merge_filters_q(
view_filters, user_filters, search_text, {
f['id']: f['info']['view_filter']
for f in unfiltered_response['fields']
if f.get(u'info', {}).get(u'view_filter')})

sort_list = []
for order in params['order']:
Expand All @@ -100,36 +108,47 @@ def filtered_download(self, resource_view_id):
action=u'dump',
resource_id=resource_view[u'resource_id'])
+ u'?' + urlencode({
u'q': search_text,
u'q': json.dumps(q),
u'sort': u','.join(sort_list),
u'filters': json.dumps(filters),
u'format': request.params['format'],
u'fields': u','.join(cols),
}))


def merge_filters(view_filters, user_filters_str):
def merge_filters_q(view_filters, user_filters_str, search_text, filter_types):
u'''
Returns (filters, q).
view filters are built as part of the view, user filters
are selected by the user interacting with the view. Any filters
selected by user may only tighten filters set in the view,
others are ignored.
>>> merge_filters({
search_text is combined with search-type filters and returned in
q dict.
>>> merge_filters_q({
... u'Department': [u'BTDT'], u'OnTime_Status': [u'ONTIME']},
... u'CASE_STATUS:Open|CASE_STATUS:Closed|Department:INFO')
{u'Department': [u'BTDT'],
u'OnTime_Status': [u'ONTIME'],
u'CASE_STATUS': [u'Open', u'Closed']}
... u'CASE_STATUS:Open|CASE_STATUS:Closed|Department:INFO',
... u'sometext',
... {u'Department': u'search'})
({u'OnTime_Status': [u'ONTIME'], u'CASE_STATUS': [u'Open', u'Closed']},
{u'': u'sometext', u'Department': u'BTDT'})
'''
filters = dict(view_filters)
if not user_filters_str:
return filters
user_filters = {}
q = {u'': search_text} if search_text else {}
for k_v in user_filters_str.split(u'|'):
k, sep, v = k_v.partition(u':')
if k not in view_filters or v in view_filters[k]:
user_filters.setdefault(k, []).append(v)
for k in user_filters:
filters[k] = user_filters[k]
return filters
for ft in filter_types:
if filter_types[ft] == u'search' and ft in filters:
q[ft] = u' '.join(filters[ft])
del filters[ft]
return filters, q

0 comments on commit 2b248f2

Please sign in to comment.