views:

172

answers:

1

I cannot seem to find a way to modify a form that has been created via:

from gluon.tools import Crud
crud = Crud(globals(), db)

form = crud.create(db.table_name)

Since I am using foreign keys in my table, the auto-generated form only allows an integer (which represents the foreign primary key), but what I want to be able to do is enter whatever data type the foreign data field requires (rather than just the identifier). Is there an easy way to tell the create() function to use the foreign table's data type rather than the primary table's data type (which is the auto-incrementing primary key)?

+1  A: 

You can use database validators to it.

It will show a select box with the values from foreign table: (from http://web2py.com/book/default/chapter/07?search=requires#Database-Validators):

IS_IN_DB

Consider the following tables and requirement:

db.define_table('person', Field('name', unique=True))
db.define_table('dog', Field('name'), Field('owner', db.person)
db.dog.owner.requires = IS_IN_DB(db, 'person.id', '%(name)s',
                                 zero=T('choose one'))

It is enforced at the level of dog INSERT/UPDATE/DELETE forms. It requires that a dog.owner be a valid id in the field person.id in the database db. Because of this validator, the dog.owner field is represented as a dropbox. The third argument of the validator is a string that describes the elements in the dropbox. In the example you want to see the person %(name)s instead of the person %(id)s. %(...)s is replaced by the value of the field in brackets for each record.

The zero option works very much like for the IS_IN_SET validator.

If you want the field validated, but you do not want a dropbox, you must put the validator in a list.

db.dog.owner.requires = [IS_IN_DB(db, 'person.id', '%(name)s')]

The first argument of the validator can be a database connection or a DAL Set, as in IS_NOT_IN_DB.

Occasionally you want the drop-box (so you do not want to use the list syntax above) yet you want to use additional validators. For this purpose the IS_IN_DB validator takes an extra argument _and that can point to a list of other validators applied if the validated value passes the IS_IN_DB validation. For example to validate all dog owners in db that are not in a subset:

subset=db(db.person.id>100)
db.dog.owner.requires = IS_IN_DB(db, 'person.id', '%(name)s',
                                 _and=IS_NOT_IN_DB(subset,'person.id'))

IS_IN_DB and Tagging

The IS_IN_DB validator has an optional attribute multiple=False. If set to True multiple values can be stored in one field. This field should be of type list:reference as discussed in Chapter 6. An explicit example of tagging is discussed there. multiple references are handled automatically in create and update forms, but they are transparent to the DAL. We strongly suggest using the jQuery multiselect plugin to render multiple fields.

Alexandre Andrade
If I choose to not use the dropbox, is there a way to make the text field auto-insert the new entry into the foreign table?
blastthisinferno