>> 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

Reply via email to