动态更新 web2py SQLFORM 中的字段

Dynamically update field in web2py SQLFORM

使用一个接近书中多对多关系示例的示例:

db = DAL("sqlites://storage.sqlite")

db.define_table('persons',
                    Field('name'))

db.define_table('things',
                    Field('name'))

db.define_table('ownership',
                    Field('person', 'reference persons'),
                    Field('thing', 'reference things'))

我还有一个 table :

db.define_table('usages',
                    Field('person', 'reference person',requires = IS_IN_DB(db, db.person.id, '%(name)s'),
                    Field('thing', 'reference thing'),
                    Field('usage'))

对于 table usages 我想为 personthing 字段设置下拉菜单,因此使用 requires .....
但是,我想让 thing 的下拉菜单根据 person 中的选择进行更改(以将选择限制为一个人拥有的东西)。 我考虑过使用 requires 来获取下拉菜单,但是我不能在 requires = IS_IN_DB(...) 中使用 db.usages.person,因为没有创建该条目,因此它会引发异常。

我尝试了什么: requires = IS_IN_DB(db, db((db.usages.person == db.persons.id) &(db.persons.id == db.ownership.person) &(db.ownership.person == db.things.name)))

使用 requires = IS_IN_DB(db,db.things.id, '%(name)s') 为我提供了 thing 的下拉菜单,但它列出了所有菜单,而不管 person 中的选择。

知道如何解决这个问题吗?

没有内置的方法来做你想做的事。您将需要使用 Javascript 来 (a) 检测何时在 person 字段中生成 selection,以及 (b) 向服务器发出 Ajax 请求以获取 thing select 元素的选项列表。

有关示例,请查看 these posts on the web2pyslices site, and also check out plugin_lazy_options_widget

此外,关于您的代码:

requires = IS_IN_DB(db, db((db.usages.person == db.persons.id) &(db.persons.id == db.ownership.person) &(db.ownership.person == db.things.name)))

请注意,IS_IN_DB 的第二个参数必须是 Field 对象或字段名称,而不是 DAL Set 对象。如果你想通过过滤器限制选项集,first 参数可以是一个 Set 对象(尽管如前所述,这在这种情况下无济于事,因为你没有在浏览器中创建 selection 之前,我不知道过滤条件是什么。