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

Reply via email to