Mercurial > p > roundup > code
diff roundup/rest.py @ 5659:1e51a709431c
Make Searching work in REST API
Previously only Links/Multilinks where the property name (e.g. "status)
is equal to the linked class name (e.g. "status") worked. Now we can
search for String, Date, Link/Multilink, with no restrictions.
Also honor the search permissions.
In the process we rename page_size, page_index parameters to the search
to @page_size and @page_index, respectively. Also renamed to add a
leading '@' was the fields parameter to data/<classname>/<id> (it is now
called @fields), and the action_name and action_args parameters to the
PATCH method on data/<classname>/<id>.
| author | Ralf Schlatterbeck <rsc@runtux.com> |
|---|---|
| date | Fri, 22 Mar 2019 09:56:10 +0100 |
| parents | 3401daf8613b |
| children | d8d2b7724292 |
line wrap: on
line diff
--- a/roundup/rest.py Thu Mar 21 11:23:09 2019 +0100 +++ b/roundup/rest.py Fri Mar 22 09:56:10 2019 +0100 @@ -493,20 +493,34 @@ 'size': None, 'index': 1 # setting just size starts at page 1 } + uid = self.db.getuid() for form_field in input.value: key = form_field.name value = form_field.value - if key.startswith("where_"): # serve the filter purpose + if key.startswith("@page_"): # serve the paging purpose key = key[6:] - filter_props[key] = [ - getattr(self.db, key).lookup(p) - for p in value.split(",") - ] - elif key.startswith("page_"): # serve the paging purpose - key = key[5:] value = int(value) page[key] = value - + else: # serve the filter purpose + prop = class_obj.getprops()[key] + # We drop properties without search permission silently + # This reflects the current behavior of other roundup + # interfaces + if not self.db.security.hasSearchPermission( + uid, class_name, key + ): + continue + if isinstance (prop, (hyperdb.Link, hyperdb.Multilink)): + vals = [] + linkcls = self.db.getclass (prop.classname) + for p in value.split(","): + if prop.try_id_parsing and p.isdigit(): + vals.append(p) + else: + vals.append(linkcls.lookup(p)) + filter_props[key] = vals + else: + filter_props[key] = value if not filter_props: obj_list = class_obj.list() else: @@ -542,11 +556,11 @@ result['@links'][rel] = [] result['@links'][rel].append({ 'rel': rel, - 'uri': "%s/%s?page_index=%s&"%(self.data_path, + 'uri': "%s/%s?@page_index=%s&"%(self.data_path, class_name,index) \ + '&'.join([ "%s=%s"%(field.name,field.value) \ for field in input.value \ - if field.name != "page_index"]) }) + if field.name != "@page_index"]) }) result['@total_size'] = result_len self.client.setHeader("X-Count-Total", str(result_len)) @@ -590,7 +604,7 @@ for form_field in input.value: key = form_field.name value = form_field.value - if key == "fields": + if key == "@fields": props = value.split(",") if key == "@protected": # allow client to request read only @@ -1027,9 +1041,9 @@ for form_field in input.value: key = form_field.name value = form_field.value - if key == "action_name": + if key == "@action_name": name = value - elif key.startswith('action_args'): + elif key.startswith('@action_args'): action_args.append(value) if name in self.actions:
