diff --git a/parlapi/rest/endpoint.py b/parlapi/rest/endpoint.py index 3e69c9b765603fbbd763ec68ab7edf76ef7e197a..d7c51ecdcf75e5eac299b813e443e89e28361f4f 100644 --- a/parlapi/rest/endpoint.py +++ b/parlapi/rest/endpoint.py @@ -6,6 +6,7 @@ from datetime import datetime from flask import abort, json, jsonify, request from sqlalchemy.inspection import inspect +from sqlalchemy.sql import not_ from .schema import SchemaFactory @@ -107,7 +108,7 @@ class Endpoint(object): raise EndpointException('Unknown column name: {}'.format(colname)) col = getattr(self.model, colname) - if op in ('eq', 'ne', 'gt', 'lt', 'gte', 'lte'): + if op in ('eq', 'ne', 'gt', 'lt', 'gte', 'lte', 'like', 'ilike'): value = self._cast_value(value, columns[colname]) if op == 'eq': @@ -122,12 +123,22 @@ class Endpoint(object): filters.append(col >= value) elif op == 'lte': filters.append(col <= value) + elif op == 'like': + filters.append(col.like(value)) + elif op == 'ilike': + filters.append(col.ilike(value)) elif op == 'isnull': null = self._cast_value(value, 'Boolean') if null: filters.append(col == None) else: filters.append(col != None) + elif op in ('in', 'nin'): + values = map(lambda x: self._cast_value(x, columns[colname]), value.split(',')) + expr = col.in_(values) + if op == 'nin': + expr = not_(expr) + filters.append(expr) else: raise EndpointException('Unknown operator: {}'.format(op)) diff --git a/parlapi/templates/rest_api_doc.html b/parlapi/templates/rest_api_doc.html index aa486eaa9ef3d2ebb2302238c17e7ab3b8dda3f1..e2e7b6a42c0497af25620302d7e62cb5e2071282 100644 --- a/parlapi/templates/rest_api_doc.html +++ b/parlapi/templates/rest_api_doc.html @@ -21,8 +21,10 @@ Il est possible de spécifier un opérateur de comparaison sous la forme `champ_ * `gt`, `gte`: supérieur, supérieur ou égal * `lt`, `lte`: inférieur, inférieur ou égal * `isnull`: permet de filtrer les valeurs vierges. La valeur associée doit être un booléen. +* `in`, `nin`: valeur parmi une liste ou absente d'une liste (les valeurs doivent alors être séparées par des virgules) +* `like`, `ilike`: comparaison de chaine avec jokers ; `ilike` est insensible à la casse (par exemple `prenom__ilike=jean%` cherche tous les prénoms commençant par "Jean") -La requête suivante permet par exemple de lister les acteurs décédés, prénommés "Jean", et nés après le 1er janvier 1945 : [`/rest/an/acteurs/?prenom=Jean&date_deces__isnull=false&date_naissance__gt=1945-01-01`](/rest/an/acteurs/?prenom=Jean&date_deces__isnull=false&date_naissance__gt=1945-01-01) +La requête suivante permet par exemple de lister les acteurs décédés, dont le prénom contient "Jean", et nés après le 1er janvier 1945 : [`/rest/an/acteurs/?prenom__ilike=%jean%&date_deces__isnull=false&date_naissance__gt=1945-01-01`](/rest/an/acteurs/?prenom__ilike=%jean%&date_deces__isnull=false&date_naissance__gt=1945-01-01) ##### Recherche *full-text*