Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 当引用表的format属性为function时,下拉列表中的web2py排序顺序_Python_Sorting_Web2py - Fatal编程技术网

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

Python 当引用表的format属性为function时,下拉列表中的web2py排序顺序,python,sorting,web2py,Python,Sorting,Web2py,Q&A和似乎表示由IS_in_DB validator生成的下拉列表中的默认排序顺序由引用表的format属性确定。但在以下情况下,默认排序顺序是引用表的“id”: db.define_table('bank', Field('bank_code', 'string', unique=True, required=True, label='Bank/FI Code'), Field('bank_name', 's

Q&A和似乎表示由IS_in_DB validator生成的下拉列表中的默认排序顺序由引用表的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_分支的lambda函数返回的标签,它们也按其id字段排序

建议在这种情况下使用is_IN_SET,但是当lambda函数执行这种格式时,根据“format”属性进行排序的正常行为会发生什么变化

默认情况下,当IS_IN_DB validator生成一组值和相关标签时,它不会直接按生成的标签排序。相反,在数据库select中,它指定一个ORDERBY子句,其中包含用于生成标签的字段。如果引用表的format属性是Python格式字符串,则标签字段将按其显示顺序从该格式字符串中提取。在这种情况下,这具有按标签排序最终集的效果

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

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

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

另一方面,请记住,如果有许多银行分行,这种生成标签的方法会有点低效,因为format函数包含一个递归选择,即r.bank.brank_代码,它对列表中的每个项目进行单独选择。另一种方法是基于连接查询生成您自己的一组值和标签,然后使用IS_IN_set validator或使用IS_IN_DB进行验证,并单独指定表单小部件及其选项。当然,在某些情况下,可能会有更多的分支包含在选择输入中,在这种情况下,您可以使用IS_in_DB进行验证,但应该使用替代输入小部件,例如Ajax自动完成。

感谢Anthony的清晰解释。我注意到的一个区别是下拉列表不是按bank_branch.bank.id排序的,而是按bank_branch.id排序的。假设id将是表定义的第一个字段,即使没有显式定义。还感谢您在使用sort=True选项时的谨慎。我的bank_branch表预计会随着时间的推移增长到大约100000条记录,递归选择最终可能会导致问题。所以这里必须遵循IS_IN_SET方法,对吗?抱歉,我们查看了错误的代码块,该ID仅在Google App Engine上从orderby中排除。我已经更正了答案。此外,如果您将有100000多条记录,那么无论如何您都不希望在表单中使用select输入,因为您将向浏览器发送所有这些记录,并且假设浏览器没有崩溃,用户将有一个超长的滚动列表。在这种情况下,您应该改为使用Ajax自动完成之类的工具,或者根据之前选择的银行等,将分支列表限制为一个子集。。