In widgets.py there is a tiny bit of code that is dependent on ZODB; I use the forms class frequently; one reason I like using it is to pass a list of objects to the select widgets as so: self.add_widget("single_select", "type", title=_("Type"), value=c.type_id, allowed_values=TYPES, size=1, required=1) I found a tiny dependency on ZODB recently in widget.py when I converted from a ZODB object store to a PostgreSQL based store. widget.py starting at line 311: def _generate_keys (self, values, descriptions): """Called if no keys were provided. Try to generate a set of keys that will be consistent between rendering and parsing. """ # try to use ZODB object IDs keys = [] for value in values: if value is None: oid = "" oid = getattr(value, "_p_oid", None) if not oid: break hi, lo = struct.unpack(">LL", oid) oid = "%x" % ((hi << 32) | lo) Can anyone see a reason why this could not be made less specific to ZODB? I'll admit to simply throwing a try/except around it, simply break 'ing out if it fails. And I'll admit to not really having looked to see why that works for me, but it does ;-) Mike