当引用表的格式属性为function时,下拉列表中的web2py排序顺序

时间:2018-11-01 11:44:07

标签: python sorting web2py

Q&A herehere似乎表明IS_IN_DB验证程序在下拉列表中的默认排序顺序由引用表的format属性确定。但是在以下情况下,默认的排序顺序是被引用表的'id':

db.define_table('bank',
            Field('bank_code', 'string',
                  unique=True, required=True, label='Bank/FI Code'),
            Field('bank_name', 'string',
                  required=True, label='Bank/FI Name'),
            singular="Bank", plural="Banks",
            format='%(bank_name)s'
            )

db.bank.bank_code.requires=IS_UPPER()
db.bank.bank_name.requires=IS_UPPER()

db.define_table('bank_branch',
            Field('bank', 'reference bank', label='Bank/FI'),
            Field('branch_name', 'string', required=True, label='Branch Name'),
            format=lambda r:'%s-%s' % (r.bank.bank_code, r.branch_name)

即使下拉标签显示表bank_branch的lambda函数返回的标签,它们也会在其id字段上排序。

建议here在这种情况下使用IS_IN_SET,但是用lambda函数完成这种格式化后,基于'format'属性进行排序的正常行为又有什么解释呢?

1 个答案:

答案 0 :(得分:1)

默认情况下,IS_IN_DB验证器生成值集和关联的标签时,它不会直接按生成的标签进行排序。而是,在数据库选择中,它指定一个ORDER BY子句,其中包括用于生成标签的字段。如果引用表的format属性是Python格式的字符串,则标签字段按照显示顺序从该格式字符串中提取。在这种情况下,这具有通过标签对最终集合进行排序的效果。

但是,如果引用表的format属性是一个函数,则IS_IN_DB不知道生成标签需要哪些字段,因此它只是选择表中的所有字段并按以下顺序排序所有字段(按照它们在表定义中出现的顺序)。在这种情况下,由于db.bank_branch.id是表定义中的第一个字段(尽管没有明确定义),所以它是ORDER BY子句中的第一个字段,从而导致选项按ID的ID排序。 db.bank_branch表。

如果要强制按生成的标签对选项进行排序,则可以使用sort参数:

IS_IN_DB(db, 'bank_branch.id', db.bank_branch._format, sort=True)

此外,请记住,如果有许多银行分支,则这种生成标签的方法效率较低,因为format函数包括一个递归选择(即r.bank.brank_code),该选择为列表中的每个项目单独选择。一种替代方法是根据联接查询生成您自己的一组值和标签,然后使用IS_IN_SET验证程序(或仅使用IS_IN_DB进行验证,并分别指定表单小部件及其选项)。当然,在某些时候,选择输入中可能包含的分支数量可能超出合理范围,在这种情况下,您可以使用IS_IN_DB进行验证,但应使用替代输入小部件(例如, Ajax自动完成)。