使用 Web2py/Python 在 SQLite 中引用另一个 table

Reference another table in SQLite using Web2py/Python

我是 Web2py 和 SQL 数据库的新手,如果这是一个愚蠢的问题,请原谅我。

我想做的是创建一个从 SQL table 中提取相关数据(类型、标签、IS_NOT_EMPTY() 等)的表单字段来填充和配置前端的输入元素。到目前为止,我已经成功地使用 Web2py Manual 作为一个很好的参考来做到这一点。

我已经到了想要使用多个 table 来帮助更有效地分类数据集的地步。最好的情况是有一个可以在我的控制器文件(default.py)中调用的主 table,它与我的其他相关(但并不总是需要)table 链接数据库

在下面的代码中你可以看到我先定义了'category_t' table,然后定义了'new_product' table。然后,我尝试在 new_product 的 'main_category' 字段中引用 'category_t' table。 'main_category' 字段最终成为表单上的多个 select 元素,这正是我想要的。我只需要使用 'category_t' 中的 字段标签 作为多 select 选项。

我使用的是 Web2py 手册中的 Links to referencing records 说明,但我认为我误解了它的实际功能。我迫切需要有人教我 Web2py 和 SQLite 的法律。

db.define_table(
    'category_t',
    Field('category1', 'boolean', label='Category 1'),
    Field('category2', 'boolean', label='Category 2'),
    Field('category3', 'boolean', label='Category 3'),
)

db.define_table(
    'new_product',
    Field('name', requires=[IS_NOT_EMPTY(), IS_ALPHANUMERIC()], label='Product Name'),
    Field('sku', requires=[IS_NOT_EMPTY(), IS_ALPHANUMERIC()], label='SKU'),
    Field('build', requires=IS_IN_SET(['Build1','Build2','Build3']), label='Product Type'),
    Field('main_category', 'list:reference category_t', label='Category'),
)



更新

我发现只需在主 table 中添加辅助 table 即可使其显示在前端。我还没有检查它是否能够无错误地更新。

db.define_table(
    'new_product',
    Field('name', requires=[IS_NOT_EMPTY(), IS_ALPHANUMERIC()], label='Product Name'),
    Field('sku', requires=[IS_NOT_EMPTY(), IS_ALPHANUMERIC()], label='SKU'),
    Field('build', requires=IS_IN_SET(['Build1','Build2','Build3']), label='Product Type'),
    db.category_t
)


我还没有想出如何将它显示为 multi-select 元素。截至目前,它显示为一系列复选框。

您更新中的代码没有按照您认为的那样进行。通过将 db.category_t 添加到 new_product table 定义,您只是将一组完全独立的类别字段添加到 new_product table。这些字段的数据将存储在 new_product table 中,category_t table 中不会存储任何内容。如果您只想要一组固定的布尔类别字段,那么 category_t table 是不必要的——您应该只在 new_product 中定义这些字段。但是,每个类别将是一个单独的输入,因此您不会有一个单一的 multi-select.

可能您想要的是 list:stringlist:reference 字段。最简单的方法是 list:string 字段:

db.define_table('new_product', ...,
    Field('main_categories', 'list:string', label='Categories',
          requires=IS_IN_SET(['Category 1', 'Category 2', 'Category 3'],
                             multiple=True)))

上面将在main_categories字段中存储类别名称列表,IS_IN_SET验证器将选项限制为一组特定的类别,这些类别将显示在多select 框(由于 multiple=True 参数)。在这种情况下不需要单独的类别 table。

如果您出于某种原因想要维护一个单独的类别 table(例如,每个类别都有一些元数据,或者您希望经常编辑类别名称),您可以改用list:reference 字段。但是,不应像您的示例中那样定义类别 table,而应为每个类别单独记录:

db.define_table('category',
    Field('name'),
    [other category metadata fields if needed],
    format='%(name)s')

db.define_table('new_product', ...,
    Field('main_categories', 'list:reference category', label='Categories')

在这种情况下,main_categories 字段将获得默认的 IS_IN_DB 验证器以及显示类别名称的多 select 小部件(这是通过美德启用的category table 定义中的 "format" 参数,设置为 "name" 字段)。

最后一个选项是设置一个完整的 many-to-many schema,这需要第三个 table。但是,这会使设置表单条目变得复杂,因为没有内置方法可以为多对多关系创建一个带有多 select 的 new_product 条目表单。