1

我只是想创建一个简单的应用程序,其中有 2 个表在模型中相互链接:

db.define_table('project',
            Field('project_name','string',unique =True),
            auth.signature)
db.define_table('watershed',
            Field('project_name', requires = IS_IN_DB(db,db.project.project_name)),
            Field('main_watershed','string', unique =True),
            auth.signature)
db.watershed.main_watershed.requires = IS_NOT_EMPTY()

在控制器中:

def add_project():
form = SQLFORM(db.project).process()
if form.accepted: redirect('add_main')
return dict(form = form)

def add_main():
form = SQLFORM(db.watershed).process()
if form.accepted: redirect('add_main')
LIST = db(db.watershed).select()
return dict(form = form, LIST = LIST) 

假设用户调用 default/add_project 并添加“Project 1”,如果用户调用 default/add_project 并再次添加“Project 1”,用户会得到错误值已存在于数据库中。

如果此过程转到 default/add_main,如果用户添加(例如在 main_watershed 字段 = MAIN 1),则弹出相同的字符串 NO 错误。

有什么遗漏吗?为什么我的价值不是唯一的?

4

1 回答 1

2

unique=True由数据库强制执行,而不是由表单验证过程强制执行。如果您尝试插入一个已经在数据库中的值,数据库应该返回一个错误,这应该会在您的 web2py 应用程序中触发一个错误(但您不会在表单上显示一个很好的错误消息)。如果您希望表单验证检查重复项,您应该使用 IS_NOT_IN_DB 验证器:

Field('main_watershed', 'string',
      requires=IS_NOT_IN_DB(db, 'watershed.main_watershed'))

此外,您可以考虑将其作为参考字段,而不是在分水岭表中存储“project_name”字段的重复项:

db.define_table('project',
    Field('project_name', 'string',unique =True),
    auth.signature,
    format='%(project_name)s')
db.define_table('watershed',
    Field('project', 'reference project'),
    Field('main_watershed', 'string',
          requires=IS_NOT_IN_DB(db, 'watershed.main_watershed')),
    auth.signature)

您还应该在重定向中使用 URL() 函数:redirect(URL('default', 'add_main'))

最后,为了更容易为最近添加的项目添加分水岭,您可以考虑将项目的 id 传递给 add_main 函数并将其设置为项目的默认值:

def add_project():
    form = SQLFORM(db.project).process()
    if form.accepted:
        redirect(URL('default', 'add_main', args=form.vars.id))
    return dict(form = form)

def add_main():
    project_id = request.args(0, cast=int, default=None)
    db.watershed.project.default = project_id
    form = SQLFORM(db.watershed).process()
    if form.accepted:
        redirect(URL('default', 'add_main', args=project_id)
    LIST = db(db.watershed).select()
    return dict(form = form, LIST = LIST) 
于 2013-10-02T19:10:55.840 回答