Domanda

I am just trying to create a simple app with 2 tables linked to each other in model:

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()

in controller:

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) 

Assuming that user calls default/add_project and adds "Project 1", if user recall the default/add_project and add again "Project 1", user get a error value already exists in the database.

If this process gone to default/add_main, if user adds (ex. in main_watershed field = MAIN 1) the same string NO error pops up.

Is something missing? Why is my value not unique?

È stato utile?

Soluzione

unique=True is enforced by the database, not by the form validation process. If you attempt to insert a value that is already in the database, the database should return an error, which should trigger an error in your web2py application (but you won't get a nice error message displaying on the form). If you want the form validation to check for duplicates, you should use the IS_NOT_IN_DB validator:

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

Also, rather than storing duplicates of the "project_name" field in the watershed table, you might consider making that a reference field:

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)

You should also use the URL() function in your redirect: redirect(URL('default', 'add_main'))

Finally, to make it easier to add watersheds for the recently added project, you might consider passing the id of the project to the add_main function and have it set that as the default value for the project:

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) 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top