>> I'll see if I can figure out a minimalist patch to >> propose... > > Eagerly waiting! But if you don't succeed notify me -- I'll at least > add a TODO item.
Not sure if this will be up to your coding standards, but here is an attempt - it uses the validator infrastructure to attempt conversion using the idType function of the foreign table. This will suffice to ensure values can be converted to the correct type, next level of validation would be to require the converted value to be a valid id for the foreign table (probably too much overhead). I think this approach is relatively consistent with the current style and conventions, but I'm sure you'll tell me if not. :-) Patch for col.py and a new test module attached. Cheers! - n -- Dr. Nathan Edwards n...@georgetown.edu Department of Biochemistry and Molecular & Cellular Biology Georgetown University Medical Center Room 1217, Harris Building, 3300 Whitehaven St, NW, Washington DC 20007 Phone: 202-687-7042, Fax: 202-687-0057
diff -r -c SQLObject-2.1.2/sqlobject/col.py SQLObject-2.1.2.new/sqlobject/col.py *** SQLObject-2.1.2/sqlobject/col.py 2014-12-14 09:21:09.000000000 -0500 --- SQLObject-2.1.2.new/sqlobject/col.py 2015-12-23 11:58:29.000000000 -0500 *************** *** 814,819 **** --- 814,844 ---- baseClass = SOKeyCol + class ForeignKeyValidator(SOValidator): + + def __init__(self,*args,**kw): + super(ForeignKeyValidator,self).__init__(*args,**kw) + self.fkIDType = None + + def to_python(self, value, state): + if self.fkIDType == None: + otherTable = findClass(self.soCol.foreignKey, self.soCol.soClass.sqlmeta.registry) + self.fkIDType = otherTable.sqlmeta.idType + if value is None: + return None + # Avoid importing the main module to get the SQLObject class for isinstance + if hasattr(value,'sqlmeta'): + return value + try: + value = self.fkIDType(value) + return value + except (ValueError, TypeError), e: + pass + raise validators.Invalid("expected a %r for the ForeignKey '%s', got %s %r instead" % \ + (self.fkIDType, self.name, type(value), value), value, state) + + from_python = to_python + class SOForeignKey(SOKeyCol): def __init__(self, **kw): *************** *** 826,831 **** --- 851,860 ---- kw['name'] = style.instanceAttrToIDAttr(style.pythonClassToAttr(foreignKey)) super(SOForeignKey, self).__init__(**kw) + def createValidators(self): + return [ForeignKeyValidator(name=self.name)] + \ + super(SOForeignKey, self).createValidators() + def sqliteCreateSQL(self): sql = SOKeyCol.sqliteCreateSQL(self) other = findClass(self.foreignKey, self.soClass.sqlmeta.registry) Only in SQLObject-2.1.2.new/sqlobject/tests: test_ForeignKey_validation.py
from sqlobject import * from sqlobject.col import validators from sqlobject.tests.dbtest import * class TestA(SQLObject): name = StringCol() bfk = ForeignKey("TestB") cfk = ForeignKey("TestC",default=None) class TestB(SQLObject): name = StringCol() afk = ForeignKey("TestA") class TestC(SQLObject): class sqlmeta: idType = str name = StringCol() def test1(): setupClass([TestA, TestB, TestC]) a = TestA(name="testa",bfk=None) b = TestB(name="testb",afk=a) c = TestC(id='testc',name="testc") a.bfk = b a.cfk = c assert(a.bfk==b) assert(a.cfk==c) assert(b.afk==a) def test2(): setupClass([TestA, TestB, TestC]) raises(validators.Invalid,TestA,name="testa",bfk='testb',cfk='testc') def test3(): setupClass([TestA, TestB, TestC]) a = TestA(name="testa",bfk=1,cfk='testc') assert(a.bfkID == 1) assert(a.cfkID == 'testc')
------------------------------------------------------------------------------
_______________________________________________ sqlobject-discuss mailing list sqlobject-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss