diff --git a/gluon/html.py b/gluon/html.py
index 8290e820..b6fc7c0c 100644
--- a/gluon/html.py
+++ b/gluon/html.py
@@ -1859,6 +1859,8 @@ class INPUT(DIV):
try:
(value, errors) = validator(value)
except:
+ import traceback
+ print traceback.format_exc()
msg = "Validation error, field:%s %s" % (name,validator)
raise Exception(msg)
if not errors is None:
diff --git a/gluon/validators.py b/gluon/validators.py
index cd2a3151..1d46d6ca 100644
--- a/gluon/validators.py
+++ b/gluon/validators.py
@@ -509,7 +509,9 @@ class IS_IN_DB(Validator):
zero='',
sort=False,
_and=None,
- left=None
+ left=None,
+ delimiter=None,
+ auto_add = False,
):
from pydal.objects import Table
if hasattr(dbset, 'define_table'):
@@ -530,19 +532,21 @@ class IS_IN_DB(Validator):
if isinstance(label, str):
if regex1.match(str(label)):
label = '%%(%s)s' % str(label).split('.')[-1]
- ks = regex2.findall(label)
- if kfield not in ks:
- ks += [kfield]
- fields = ks
+ fieldnames = regex2.findall(label)
+ if kfield not in fieldnames:
+ fieldnames.append(kfield) # kfield must be last
+ elif isinstance(label, Field):
+ fieldnames = [label.name, kfield] # kfield must be last
+ label = '%%(%s)s' % label.name
+ elif callable(label):
+ fieldnames = '*'
else:
- ks = [kfield]
- fields = 'all'
+ raise NotImplementedError
self.field = field # the lookup field
- self.fields = fields # fields requires to build the formatting
+ self.fieldnames = fieldnames # fields requires to build the formatting
self.label = label
self.ktable = ktable
self.kfield = kfield
- self.ks = ks
self.error_message = error_message
self.theset = None
self.orderby = orderby
@@ -554,6 +558,8 @@ class IS_IN_DB(Validator):
self.sort = sort
self._and = _and
self.left = left
+ self.delimiter = delimiter
+ self.auto_add = auto_add
def set_self_id(self, id):
if self._and:
@@ -561,10 +567,10 @@ class IS_IN_DB(Validator):
def build_set(self):
table = self.dbset.db[self.ktable]
- if self.fields == 'all':
+ if self.fieldnames == '*':
fields = [f for f in table]
else:
- fields = [table[k] for k in self.fields]
+ fields = [table[k] for k in self.fieldnames]
ignore = (FieldVirtual, FieldMethod)
fields = filter(lambda f: not isinstance(f, ignore), fields)
if self.dbset.db._dbname != 'gae':
@@ -585,8 +591,6 @@ class IS_IN_DB(Validator):
self.theset = [str(r[self.kfield]) for r in records]
if isinstance(self.label, str):
self.labels = [self.label % r for r in records]
- elif isinstance(self.label, Field):
- self.labels = [r[self.label.name] for r in records]
else:
self.labels = [self.label(r) for r in records]
@@ -599,18 +603,44 @@ class IS_IN_DB(Validator):
items.insert(0, ('', self.zero))
return items
+ def maybe_add(self, table, fieldname, value):
+ d = {fieldname: value}
+ record = table(**d)
+ if record:
+ return record.id
+ else:
+ return table.insert(**d)
+
def __call__(self, value):
table = self.dbset.db[self.ktable]
field = table[self.kfield]
+
+ print self.kfield, value, self.multiple
+
if self.multiple:
if self._and:
raise NotImplementedError
if isinstance(value, list):
values = value
+ elif self.delimiter:
+ values = value.split(self.delimiter) # because of autocomplete
elif value:
values = [value]
else:
values = []
+ print values
+ if self.field.type in ('id','integer'):
+ new_values = []
+ for value in values:
+ if isinstance(value,(int,long)) or value.isdigit():
+ value = int(value)
+ elif self.auto_add:
+ value = self.maybe_add(table, self.fieldnames[0], value)
+ else:
+ return (values, translate(self.error_message))
+ new_values.append(value)
+ values = new_values
+ print value
if isinstance(self.multiple, (tuple, list)) and \
not self.multiple[0] <= len(values) < self.multiple[1]:
return (values, translate(self.error_message))
@@ -629,18 +659,32 @@ class IS_IN_DB(Validator):
return (values, None)
elif count(values) == len(values):
return (values, None)
- elif self.theset:
- if str(value) in self.theset:
- if self._and:
- return self._and(value)
- else:
- return (value, None)
else:
- if self.dbset(field == value).count():
- if self._and:
- return self._and(value)
+ if self.field.type in ('id','integer'):
+ if isinstance(value,(int,long)) or value.isdigit():
+ value = int(value)
+ elif self.auto_add:
+ value = self.maybe_add(table, self.fieldnames[0], value)
else:
- return (value, None)
+ return (value, translate(self.error_message))
+
+ try:
+ value = int(value)
+ except TypeError:
+ return (values, translate(self.error_message))
+
+ if self.theset:
+ if str(value) in self.theset:
+ if self._and:
+ return self._and(value)
+ else:
+ return (value, None)
+ else:
+ if self.dbset(field == value).count():
+ if self._and:
+ return self._and(value)
+ else:
+ return (value, None)
return (value, translate(self.error_message))