Thanks for all the advice on this, I really appreciate it. I've managed
to get this working by using the code below. You use it like this:
class SomeDomainObject(SQLObject):
...etc
# This will create a new object in the database
form = FormValues(clazz = SomeDomainObject)
form.attr1 = 'value1'
form.attr2 = 'value2'
form.save() #Insert deferred to here
# This will update an existing object
obj = SomeDomainObject.select(...)
form = FormValues(object = obj)
form.attr1 = 'newvalue'
form.attr2 = 'newValue2'
form.save() #Update deferred to here
This code works but I'm not very keen on it because it seems like a hack
to, in particular using "eval" to call the object constructor does not
feel good. Any advice or comments on how to improve this are welcome.
Cheers
Peter
class FormValues:
def __init__(self, clazz = None, object = None):
self.clazz = clazz
self.object = object
def __getattr__(self, attr):
# If we just want the object (as in 'self.object')
if attr == 'object' and self.__dict__.has_key('object'):
return self.__dict__['object']
# Otherwise, if we have an object, pass the call to it
elif self.__dict__.has_key('object') and self.__dict__['object']
is not None:
return getattr(self.__dict__['object'], attr)
# Otherwise return the attr we have (or None if not found)
else:
if self.__dict__.has_key(attr):
return self.__dict__[attr]
else:
return None
def __setattr__(self, attr, val):
# Store the attribute to set it on the object later
self.__dict__[attr] = val
def save(self):
# If we haven't been created with an object, create one
if self.object is None:
initStrings = []
removeAttrs = []
allAttrs = self.__dict__.keys()
for col in self.clazz._SO_columns:
if self.__dict__.has_key(col.name):
initStrings.append('%s = self.%s' % (col.name,
col.name))
allAttrs.remove(col.name)
removeAttrs.append(col.name)
elif col.default is not None and col.default !=
sqlobject.sqlbuilder.NoDefault:
initStrings.append("%s = %s" % (col.name,
`col.default`))
else:
initStrings.append('%s = None' % (col.name))
initString = '%s(%s)' % (self.clazz.__name__,
string.join(initStrings, ','))
self.object = eval(initString)
for attr in removeAttrs:
del self.__dict__[attr]
# Set the attributes that are not columns
for key in allAttrs:
if key != 'object' and key != 'clazz':
setattr(self.object, key, self.__dict__[key])
del self.__dict__[key]
else:
# Otherwise set the values on the object we have
for key in self.__dict__.keys():
if key != 'object' and key != 'clazz':
setattr(self.object, key, self.__dict__[key])
del self.__dict__[key]
> On Thu, 2004-12-09 at 05:51, Ian Bicking wrote:
> > Peter Butler wrote:
> > > I'm just getting to grips with SQLObject so please pardon me if this
> > > is a question that has been asked before.
> > >
> > > Is it possible to defer the insert/update so that the object can be
> > > validated before the changes are written to the database?
> > >
> > > I would like to be able to do the following:
> > >
> > > object = MyObject()
> > > object.field1 = someValue
> > > object.field2 = someValue
> > > object.validate() object.save()
> > >
> > > With similar logic for objects that already exist in the database.
> > >
> > > From looking through the tutorial and source the philosophy seems
> > > to be to write all object changes to the database as they occur.
> > > This makes sense to me as it simplifies everything.
> >
> > You can also set several keys at once using .set(); you might require
> > that the object be valid for each call to .set(). You can also delay
> > saves to the database with _lazyUpdate = True, then you can override the
> > .syncUpdate() method to do validation. Hmm... apparently I haven't
> > included lazyUpdate in the docs, but it is noted in the News.
|