import locale
locale.setlocale(locale.LC_ALL, 'cs_CZ.UTF-8') # in multi-languages environment use PyICU instead (thx Niphlod)
class IS_IN_DB_(IS_IN_DB):
def build_set(self):
super(IS_IN_DB_, self).build_set()
records = [(lbl, self.theset[pos]) for pos, lbl in enumerate(self.labels)]
records.sort(key=lambda x: locale.strxfrm(x[0]))
self.labels = [rec[0] for rec in records]
self.theset = [rec[1] for rec in records]
db.define_table('payment',
Field('idauth_user', 'reference auth_user', requires=IS_EMPTY_OR(IS_IN_DB_(db, db.auth_user.id, '%(nick)s'))),
...)
... or to any other special order.For me was creazy that I was not able to sort items (names) in IS_IN_DB lists alphabetically.IS_IN_DB has lot of undocumented parameters but I think nothing can help.Of course when running from Postgres, you will receive records with proper locale order.However with SQLite you need (maybe) a hacked and special compiled SQLite to have correct order.Otherwise you start with uppercase ascii, then follow lowercase ascii, and at the end are accented (non-ascii) characters. Crazy.Now I use this hack in my model:
import locale
locale.setlocale(locale.LC_ALL, 'cs_CZ.UTF-8')
class IS_IN_DB_(IS_IN_DB):
def build_set(self):
super(IS_IN_DB_, self).build_set()
records = [(lbl, self.theset[pos]) for pos, lbl in enumerate(self.labels)]
records.sort(key=lambda x: locale.strxfrm(x[0]))
self.labels = [rec[0] for rec in records]
self.theset = [rec[1] for rec in records]
db.define_table('payment',
Field('idauth_user', 'reference auth_user', requires=IS_EMPTY_OR(IS_IN_DB_(db, db.auth_user.id, '%(nick)s'))),
...)
BTW: setlocale is not threadsafe.
Applications typically start with a call of
This sets the locale for all categories to the user’s default setting (typically specified in the LANG environment variable). If the locale is not changed thereafter, using multithreading should not cause problems.
Thanks, Anthony.When I have some time maybe I will do more experiments.With sort=True I was (earlier) not sucessful. Because I think I need a lambda to set the order, boolean is not enough.Inside options() I had (earlier) the set_trace point but I wasn't successful to stop the execution there. Not sure if it is called in form preparing/rendering.