All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Eggleton <paul.eggleton@linux.intel.com>
To: yocto@yoctoproject.org
Subject: [layerindex-web][PATCH] Handle __isnull in API query filtering
Date: Mon,  5 Feb 2018 10:52:04 +1300	[thread overview]
Message-ID: <20180204215204.19189-1-paul.eggleton@linux.intel.com> (raw)

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@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



                 reply	other threads:[~2018-02-04 21:52 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180204215204.19189-1-paul.eggleton@linux.intel.com \
    --to=paul.eggleton@linux.intel.com \
    --cc=yocto@yoctoproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.