> What's the problem with:
> s = SelectField("categoryID", labeltext="Choose a category",
> options=[(cat.id, cat.name) for cat in model.Category.select()],
> validator=IntValidator())
The problem is that options value is set at the construction and not at
runtime (when displayed, usefull when data change).
In my case instead of a function, I use an instance of Voculabulary :
class Vocabulary:
""" trivial vocabulary implementation for dict and iterable (like
list, tuple,...) """
def __init__(self, items):
self._items = []
if dict == type(items):
for key, item in items:
self._items.append((key, item))
elif hasattr(items, '__iter__'):
#for tuple and list
for item in items:
self._items.append((item, item))
#order by label
self._items.sort(self.cmpLabel)
def cmpLabel(self, x, y):
return cmp(x[1], y[1])
def items(self):
""" return (id, label) pairs, ordered by id (use in edit
screen)"""
return self._items
def item(self, id):
""" find a specific item (use in list/result of search
screen)"""
for itemid, label in self.items():
if itemid == id:
return label
return None
class SQLVocabulary(Vocabulary):
""" generate a vocabulary out of an SQLObject
use the 'labelcol' or the value of the 'label' attribute of
the SQLObject(if defined),
the labelcol(ulmn) is use for display
"""
def __init__(self, sqlobj, labelcol = None):
self._items = None
self.sqlobj = sqlobj
if labelcol is None:
if hasattr(sqlobj, 'label'):
labelcol = 'label'
else:
labelcol = 'id'
self.labelfield = labelcol
def items(self):
""" return (id, label) pairs, ordered by label """
resultset = self.sqlobj.select()
items = []
for item in resultset:
items.append((item.id, getattr(item, self.labelfield)))
items.sort(self.cmpLabel)
return items
def item(self, id):
""" find a specific item,
use to display the label instead of the id of join or foreign
field
"""
if id is None:
return ""
item = self.sqlobj.select(id)
return getattr(item, self.labelfield)