Repository: web2py/web2py

Issue:
IS_IN_DB validator - add left argument for LEFT JOIN
_From [ato.st...@gmail.com](https://code.google.com/u/117176497741954485102/) on April 15, 2013 21:00:46_

Can a 'left' argument be added to include a left join in the SQL statment?  I had a situation where I needed to display the text from a related table in my dropdown list generated by web2py.  I got it working but the code is ugly and a 'left' argument would have been a more elegant solution.

_Original issue: http://code.google.com/p/web2py/issues/detail?id=1454_



Discussion:
_From [massimo....@gmail.com](https://code.google.com/u/111721297562664670951/) on April 15, 2013 20:55:17_

**Status:** Accepted  

_From [massimo....@gmail.com](https://code.google.com/u/111721297562664670951/) on June 10, 2013 04:22:25_

**Labels:** -Type-Defect Type-Enhancement  


Resolving patch:
diff --git a/gluon/validators.py b/gluon/validators.py
--- a/gluon/validators.py
+++ b/gluon/validators.py
@@ -505,6 +505,7 @@ def __init__(
         zero='',
         sort=False,
         _and=None,
+        left=None
     ):
         from pydal.objects import Table
         if isinstance(field, Table):
@@ -521,7 +522,7 @@ def __init__(
             if regex1.match(str(label)):
                 label = '%%(%s)s' % str(label).split('.')[-1]
             ks = regex2.findall(label)
-            if not kfield in ks:
+            if kfield not in ks:
                 ks += [kfield]
             fields = ks
         else:
@@ -542,6 +543,7 @@ def __init__(
         self.zero = zero
         self.sort = sort
         self._and = _and
+        self.left = left
 
     def set_self_id(self, id):
         if self._and:
@@ -553,15 +555,16 @@ def build_set(self):
             fields = [f for f in table]
         else:
             fields = [table[k] for k in self.fields]
-        ignore = (FieldVirtual,FieldMethod)
-        fields = filter(lambda f:not isinstance(f,ignore), fields)
+        ignore = (FieldVirtual, FieldMethod)
+        fields = filter(lambda f: not isinstance(f, ignore), fields)
         if self.dbset.db._dbname != 'gae':
             orderby = self.orderby or reduce(lambda a, b: a | b, fields)
             groupby = self.groupby
             distinct = self.distinct
+            left = self.left
             dd = dict(orderby=orderby, groupby=groupby,
                       distinct=distinct, cache=self.cache,
-                      cacheable=True)
+                      cacheable=True, left=left)
             records = self.dbset(table).select(*fields, **dd)
         else:
             orderby = self.orderby or \
@@ -580,7 +583,7 @@ def options(self, zero=True):
         items = [(k, self.labels[i]) for (i, k) in enumerate(self.theset)]
         if self.sort:
             items.sort(options_sorter)
-        if zero and not self.zero is None and not self.multiple:
+        if zero and self.zero is not None and not self.multiple:
             items.insert(0, ('', self.zero))
         return items
 
@@ -600,7 +603,7 @@ def __call__(self, value):
                     not self.multiple[0] <= len(values) < self.multiple[1]:
                 return (values, translate(self.error_message))
             if self.theset:
-                if not [v for v in values if not v in self.theset]:
+                if not [v for v in values if v not in self.theset]:
                     return (values, None)
             else:
                 from pydal.adapters import GoogleDatastoreAdapter


Test patch: