IS_IN_DB(...,delimiter=',',auto_add=True)
This commit is contained in:
@@ -1859,6 +1859,8 @@ class INPUT(DIV):
|
|||||||
try:
|
try:
|
||||||
(value, errors) = validator(value)
|
(value, errors) = validator(value)
|
||||||
except:
|
except:
|
||||||
|
import traceback
|
||||||
|
print traceback.format_exc()
|
||||||
msg = "Validation error, field:%s %s" % (name,validator)
|
msg = "Validation error, field:%s %s" % (name,validator)
|
||||||
raise Exception(msg)
|
raise Exception(msg)
|
||||||
if not errors is None:
|
if not errors is None:
|
||||||
|
|||||||
+67
-23
@@ -509,7 +509,9 @@ class IS_IN_DB(Validator):
|
|||||||
zero='',
|
zero='',
|
||||||
sort=False,
|
sort=False,
|
||||||
_and=None,
|
_and=None,
|
||||||
left=None
|
left=None,
|
||||||
|
delimiter=None,
|
||||||
|
auto_add = False,
|
||||||
):
|
):
|
||||||
from pydal.objects import Table
|
from pydal.objects import Table
|
||||||
if hasattr(dbset, 'define_table'):
|
if hasattr(dbset, 'define_table'):
|
||||||
@@ -530,19 +532,21 @@ class IS_IN_DB(Validator):
|
|||||||
if isinstance(label, str):
|
if isinstance(label, str):
|
||||||
if regex1.match(str(label)):
|
if regex1.match(str(label)):
|
||||||
label = '%%(%s)s' % str(label).split('.')[-1]
|
label = '%%(%s)s' % str(label).split('.')[-1]
|
||||||
ks = regex2.findall(label)
|
fieldnames = regex2.findall(label)
|
||||||
if kfield not in ks:
|
if kfield not in fieldnames:
|
||||||
ks += [kfield]
|
fieldnames.append(kfield) # kfield must be last
|
||||||
fields = ks
|
elif isinstance(label, Field):
|
||||||
|
fieldnames = [label.name, kfield] # kfield must be last
|
||||||
|
label = '%%(%s)s' % label.name
|
||||||
|
elif callable(label):
|
||||||
|
fieldnames = '*'
|
||||||
else:
|
else:
|
||||||
ks = [kfield]
|
raise NotImplementedError
|
||||||
fields = 'all'
|
|
||||||
self.field = field # the lookup field
|
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.label = label
|
||||||
self.ktable = ktable
|
self.ktable = ktable
|
||||||
self.kfield = kfield
|
self.kfield = kfield
|
||||||
self.ks = ks
|
|
||||||
self.error_message = error_message
|
self.error_message = error_message
|
||||||
self.theset = None
|
self.theset = None
|
||||||
self.orderby = orderby
|
self.orderby = orderby
|
||||||
@@ -554,6 +558,8 @@ class IS_IN_DB(Validator):
|
|||||||
self.sort = sort
|
self.sort = sort
|
||||||
self._and = _and
|
self._and = _and
|
||||||
self.left = left
|
self.left = left
|
||||||
|
self.delimiter = delimiter
|
||||||
|
self.auto_add = auto_add
|
||||||
|
|
||||||
def set_self_id(self, id):
|
def set_self_id(self, id):
|
||||||
if self._and:
|
if self._and:
|
||||||
@@ -561,10 +567,10 @@ class IS_IN_DB(Validator):
|
|||||||
|
|
||||||
def build_set(self):
|
def build_set(self):
|
||||||
table = self.dbset.db[self.ktable]
|
table = self.dbset.db[self.ktable]
|
||||||
if self.fields == 'all':
|
if self.fieldnames == '*':
|
||||||
fields = [f for f in table]
|
fields = [f for f in table]
|
||||||
else:
|
else:
|
||||||
fields = [table[k] for k in self.fields]
|
fields = [table[k] for k in self.fieldnames]
|
||||||
ignore = (FieldVirtual, FieldMethod)
|
ignore = (FieldVirtual, FieldMethod)
|
||||||
fields = filter(lambda f: not isinstance(f, ignore), fields)
|
fields = filter(lambda f: not isinstance(f, ignore), fields)
|
||||||
if self.dbset.db._dbname != 'gae':
|
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]
|
self.theset = [str(r[self.kfield]) for r in records]
|
||||||
if isinstance(self.label, str):
|
if isinstance(self.label, str):
|
||||||
self.labels = [self.label % r for r in records]
|
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:
|
else:
|
||||||
self.labels = [self.label(r) for r in records]
|
self.labels = [self.label(r) for r in records]
|
||||||
|
|
||||||
@@ -599,18 +603,44 @@ class IS_IN_DB(Validator):
|
|||||||
items.insert(0, ('', self.zero))
|
items.insert(0, ('', self.zero))
|
||||||
return items
|
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):
|
def __call__(self, value):
|
||||||
table = self.dbset.db[self.ktable]
|
table = self.dbset.db[self.ktable]
|
||||||
field = table[self.kfield]
|
field = table[self.kfield]
|
||||||
|
|
||||||
|
print self.kfield, value, self.multiple
|
||||||
|
|
||||||
if self.multiple:
|
if self.multiple:
|
||||||
if self._and:
|
if self._and:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
values = value
|
values = value
|
||||||
|
elif self.delimiter:
|
||||||
|
values = value.split(self.delimiter) # because of autocomplete
|
||||||
elif value:
|
elif value:
|
||||||
values = [value]
|
values = [value]
|
||||||
else:
|
else:
|
||||||
values = []
|
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 \
|
if isinstance(self.multiple, (tuple, list)) and \
|
||||||
not self.multiple[0] <= len(values) < self.multiple[1]:
|
not self.multiple[0] <= len(values) < self.multiple[1]:
|
||||||
return (values, translate(self.error_message))
|
return (values, translate(self.error_message))
|
||||||
@@ -629,18 +659,32 @@ class IS_IN_DB(Validator):
|
|||||||
return (values, None)
|
return (values, None)
|
||||||
elif count(values) == len(values):
|
elif count(values) == len(values):
|
||||||
return (values, None)
|
return (values, None)
|
||||||
elif self.theset:
|
|
||||||
if str(value) in self.theset:
|
|
||||||
if self._and:
|
|
||||||
return self._and(value)
|
|
||||||
else:
|
|
||||||
return (value, None)
|
|
||||||
else:
|
else:
|
||||||
if self.dbset(field == value).count():
|
if self.field.type in ('id','integer'):
|
||||||
if self._and:
|
if isinstance(value,(int,long)) or value.isdigit():
|
||||||
return self._and(value)
|
value = int(value)
|
||||||
|
elif self.auto_add:
|
||||||
|
value = self.maybe_add(table, self.fieldnames[0], value)
|
||||||
else:
|
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))
|
return (value, translate(self.error_message))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user