Merge pull request #1610 from geomapdev/dal-enhancements
handle reference fields for keyed tables
This commit is contained in:
+41
-22
@@ -54,28 +54,47 @@ def _default_validators(db, field):
|
||||
requires.append(validators.IS_TIME())
|
||||
elif field_type == 'datetime':
|
||||
requires.append(validators.IS_DATETIME())
|
||||
elif db and field_type.startswith('reference') and \
|
||||
field_type.find('.') < 0 and \
|
||||
field_type[10:] in db.tables:
|
||||
referenced = db[field_type[10:]]
|
||||
if hasattr(referenced, '_format') and referenced._format:
|
||||
requires = validators.IS_IN_DB(db, referenced._id,
|
||||
referenced._format)
|
||||
if field.unique:
|
||||
requires._and = validators.IS_NOT_IN_DB(db, field)
|
||||
if field.tablename == field_type[10:]:
|
||||
return validators.IS_EMPTY_OR(requires)
|
||||
return requires
|
||||
elif db and field_type.startswith('list:reference') and \
|
||||
field_type.find('.') < 0 and \
|
||||
field_type[15:] in db.tables:
|
||||
referenced = db[field_type[15:]]
|
||||
if hasattr(referenced, '_format') and referenced._format:
|
||||
requires = validators.IS_IN_DB(db, referenced._id,
|
||||
referenced._format, multiple=True)
|
||||
else:
|
||||
requires = validators.IS_IN_DB(db, referenced._id,
|
||||
multiple=True)
|
||||
elif db and field_type.startswith('reference'):
|
||||
if field_type.find('.') < 0 and field_type[10:] in db.tables:
|
||||
referenced = db[field_type[10:]]
|
||||
if hasattr(referenced, '_format') and referenced._format:
|
||||
requires = validators.IS_IN_DB(db, referenced._id,referenced._format)
|
||||
else:
|
||||
requires = validators.IS_IN_DB(db, referenced._id)
|
||||
elif field_type.find('.') > 0 and field_type[10:].split('.')[0] in db.tables:
|
||||
table_field = field_type[10:].split('.')
|
||||
table_name=table_field[0]
|
||||
field_name=table_field[1]
|
||||
referenced = db[table_name]
|
||||
if hasattr(referenced, '_format') and referenced._format:
|
||||
requires = validators.IS_IN_DB(db, referenced[field_name],referenced._format)
|
||||
else:
|
||||
requires = validators.IS_IN_DB(db, referenced[field_name])
|
||||
if field.unique:
|
||||
requires._and = validators.IS_NOT_IN_DB(db, field)
|
||||
if not field.notnull:
|
||||
requires = validators.IS_EMPTY_OR(requires)
|
||||
return requires
|
||||
elif db and field_type.startswith('list:reference'):
|
||||
if field_type.find('.') < 0 and field_type[15:] in db.tables:
|
||||
referenced = db[field_type[15:]]
|
||||
if hasattr(referenced, '_format') and referenced._format:
|
||||
requires = validators.IS_IN_DB(db, referenced._id,
|
||||
referenced._format, multiple=True)
|
||||
else:
|
||||
requires = validators.IS_IN_DB(db, referenced._id,
|
||||
multiple=True)
|
||||
elif field_type.find('.') > 0 and field_type[15:].split('.')[0] in db.tables:
|
||||
table_field = field_type[15:].split('.')
|
||||
table_name=table_field[0]
|
||||
field_name=table_field[1]
|
||||
referenced = db[table_name]
|
||||
if hasattr(referenced, '_format') and referenced._format:
|
||||
requires = validators.IS_IN_DB(db, referenced[field_name],
|
||||
referenced._format, multiple=True)
|
||||
else:
|
||||
requires = validators.IS_IN_DB(db, referenced[field_name],
|
||||
multiple=True)
|
||||
if field.unique:
|
||||
requires._and = validators.IS_NOT_IN_DB(db, field)
|
||||
if not field.notnull:
|
||||
|
||||
@@ -278,8 +278,68 @@ class TestValidators(unittest.TestCase):
|
||||
self.assertEqual(rtn, ('jerry', 'oops'))
|
||||
rtn = IS_IN_DB(db, 'person.id', '%(name)s', auto_add=True)('jerry')
|
||||
self.assertEqual(rtn, (3, None))
|
||||
# Test it works with reference table
|
||||
db.define_table('ref_table',
|
||||
Field('name'),
|
||||
Field('person_id', 'reference person')
|
||||
)
|
||||
ret = db.ref_table.validate_and_insert(name='test reference table')
|
||||
self.assertFalse(list(ret.errors))
|
||||
ret = db.ref_table.validate_and_insert(name='test reference table', person_id=george_id)
|
||||
self.assertFalse(list(ret.errors))
|
||||
rtn = IS_IN_DB(db, 'ref_table.person_id', '%(name)s')(george_id)
|
||||
self.assertEqual(rtn, (george_id, None))
|
||||
# Test it works with reference table.field and keyed table
|
||||
db.define_table('person_keyed',
|
||||
Field('name'),
|
||||
primarykey=['name'])
|
||||
db.person_keyed.insert(name='george')
|
||||
db.person_keyed.insert(name='costanza')
|
||||
rtn = IS_IN_DB(db, 'person_keyed.name')('george')
|
||||
self.assertEqual(rtn, ('george', None))
|
||||
db.define_table('ref_table_field',
|
||||
Field('name'),
|
||||
Field('person_name', 'reference person_keyed.name')
|
||||
)
|
||||
ret = db.ref_table_field.validate_and_insert(name='test reference table.field')
|
||||
self.assertFalse(list(ret.errors))
|
||||
ret = db.ref_table_field.validate_and_insert(name='test reference table.field', person_name='george')
|
||||
self.assertFalse(list(ret.errors))
|
||||
vldtr = IS_IN_DB(db, 'ref_table_field.person_name', '%(name)s')
|
||||
vldtr.options()
|
||||
rtn = vldtr('george')
|
||||
self.assertEqual(rtn, ('george', None))
|
||||
# Test it works with list:reference table
|
||||
db.define_table('list_ref_table',
|
||||
Field('name'),
|
||||
Field('person_list', 'list:reference person'))
|
||||
ret = db.list_ref_table.validate_and_insert(name='test list:reference table')
|
||||
self.assertFalse(list(ret.errors))
|
||||
ret = db.list_ref_table.validate_and_insert(name='test list:reference table', person_list=[george_id,costanza_id])
|
||||
self.assertFalse(list(ret.errors))
|
||||
vldtr = IS_IN_DB(db, 'list_ref_table.person_list')
|
||||
vldtr.options()
|
||||
rtn = vldtr([george_id,costanza_id])
|
||||
self.assertEqual(rtn, ([george_id,costanza_id], None))
|
||||
# Test it works with list:reference table.field and keyed table
|
||||
#db.define_table('list_ref_table_field',
|
||||
# Field('name'),
|
||||
# Field('person_list', 'list:reference person_keyed.name'))
|
||||
#ret = db.list_ref_table_field.validate_and_insert(name='test list:reference table.field')
|
||||
#self.assertFalse(list(ret.errors))
|
||||
#ret = db.list_ref_table_field.validate_and_insert(name='test list:reference table.field', person_list=['george','costanza'])
|
||||
#self.assertFalse(list(ret.errors))
|
||||
#vldtr = IS_IN_DB(db, 'list_ref_table_field.person_list')
|
||||
#vldtr.options()
|
||||
#rtn = vldtr(['george','costanza'])
|
||||
#self.assertEqual(rtn, (['george','costanza'], None))
|
||||
db.person.drop()
|
||||
db.category.drop()
|
||||
db.person_keyed.drop()
|
||||
db.ref_table.drop()
|
||||
db.ref_table_field.drop()
|
||||
db.list_ref_table.drop()
|
||||
#db.list_ref_table_field.drop()
|
||||
|
||||
def test_IS_NOT_IN_DB(self):
|
||||
from gluon.dal import DAL, Field
|
||||
|
||||
Reference in New Issue
Block a user