web2py 的 pyDAL 中 `required=True` 和 `IS_NOT_IN_DB` 的等价性

Equivalance of `required=True` and `IS_NOT_IN_DB` in web2py's pyDAL

web2py书给出了an example of modelling an image blog。与我的问题相关的代码行是:

db.define_table('image',
                Field('title', unique=True),
                Field('file', 'upload'),
                format = '%(title)s')

db.image.title.requires = IS_NOT_IN_DB(db, db.image.title)

文本指出像 db.image.title.requires 这样的表达式是验证器。但是

  1. 不清楚表达式 Field('title', unique=True) 中的 unique=True 是否也是具有完全相同功能的验证器
  2. 验证器对数据库驱动的表单生成有何影响。

摘自本书:

Notice that requires=... is enforced at the level of forms, required=True is enforced at the level of the DAL (insert), while notnull, unique and ondelete are enforced at the level of the database. While they sometimes may seem redundant, it is important to maintain the distinction when programming with the DAL.

unique=True 而不是 会导致创建验证器。当 web2py 首次在数据库中创建 table 时(假设您已启用迁移),它会导致将 UNIQUE 约束添加到数据库模式。如果您使用违反此约束的值调用 DAL .insert().update() 方法,数据库将抛出错误(这将导致您的应用程序出现 Python 异常)。

设置 requires=IS_NOT_IN_DB(...) 创建一个验证器,当您 (a) 提交使用 SQLFORM 创建的表单或 (b) 调用 DAL .validate_and_insert() 时,它将是 运行或 .validate_and_update() 方法。如果验证失败,insert/update 根本不会发送到数据库,并且您不会得到 Python 异常,而只是失败的记录(通常显示在案例中的表单上表单提交)。

如果您将通过表单进行插入和更新,使用验证器是个好主意,因为它提供了正确的用户体验(即,在表单中显示错误消息)。设置 unique=True 也是一个好主意,以便数据库具有适当的模式,以防您通过表单以外的方式(甚至可能在 web2py 或 DAL 之外)制作 inserts/updates。