[yocto] [layerindex-web][PATCH] Handle __isnull in API query filtering

Paul Eggleton paul.eggleton at linux.intel.com
Sun Feb 4 13:52:04 PST 2018


If you query on a boolean field you can use the string "False" to match
False in the database; however if you try the same with __isnull then
the query will match every record which is obviously undesirable. If
__isnull is being used, then convert the value to a boolean so that the
query works properly.

An example of this type of query:

  http://127.0.0.1:8000/layerindex/api/layerBranches/?filter=yp_compatible_version__isnull:false

Signed-off-by: Paul Eggleton <paul.eggleton at linux.intel.com>
---
 layerindex/querysethelper.py | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/layerindex/querysethelper.py b/layerindex/querysethelper.py
index b4d30c2..4e7cac5 100644
--- a/layerindex/querysethelper.py
+++ b/layerindex/querysethelper.py
@@ -28,16 +28,16 @@ VALUE_SEPARATOR = "!"
 DESCENDING = "-"
 
 def __get_q_for_val(name, value):
-    if "OR" in value:
-        return functools.reduce(operator.or_, map(lambda x: __get_q_for_val(name, x), [ x for x in value.split("OR") ]))
-    if "AND" in value:
-        return functools.reduce(operator.and_, map(lambda x: __get_q_for_val(name, x), [ x for x in value.split("AND") ]))
-    if value.startswith("NOT"):
-        kwargs = { name : value.strip("NOT") }
-        return ~Q(**kwargs)
-    else:
-        kwargs = { name : value }
-        return Q(**kwargs)
+    if isinstance(value, str):
+        if "OR" in value:
+            return functools.reduce(operator.or_, map(lambda x: __get_q_for_val(name, x), [ x for x in value.split("OR") ]))
+        if "AND" in value:
+            return functools.reduce(operator.and_, map(lambda x: __get_q_for_val(name, x), [ x for x in value.split("AND") ]))
+        if value.startswith("NOT"):
+            kwargs = { name : value.strip("NOT") }
+            return ~Q(**kwargs)
+    kwargs = { name : value }
+    return Q(**kwargs)
 
 def _get_filtering_query(filter_string):
 
@@ -46,6 +46,10 @@ def _get_filtering_query(filter_string):
     values = search_terms[1].split(VALUE_SEPARATOR)
 
     querydict = dict(zip(keys, values))
+    for key in keys:
+        if key.endswith('__isnull'):
+            querydict[key] = (querydict[key].lower() == 'true')
+
     return functools.reduce(operator.and_, map(lambda x: __get_q_for_val(x, querydict[x]), [k for k in querydict]))
 
 # we check that the input comes in a valid form that we can recognize
-- 
2.9.5




More information about the yocto mailing list