Merge pull request #1610 from geomapdev/dal-enhancements

handle reference fields for keyed tables
This commit is contained in:
mdipierro
2017-11-13 21:24:07 -06:00
committed by GitHub
2 changed files with 101 additions and 22 deletions
+41 -22
View File
@@ -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:
+60
View File
@@ -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