Foreign Key fields as null?

461 views
Skip to first unread message

joe

unread,
Jul 17, 2012, 10:26:52 AM7/17/12
to web...@googlegroups.com
Is there any way to make a field in a form referencing a foreign key null, while storing a foreign key as a foreign key, but making dropdowns corrospond to the format.  Here is my example:

Model:
db = DAL('sqlite://storage.sqlite')

db.define_table('person',
Field('name'),
Field('email'),
format = '%(name)s')

db.define_table('dog',
Field('name'),
Field('owner', requires = IS_EMPTY_OR(IS_IN_DB(db,db.person))), #I have also tried default=None, and required = False, no difference
format = '%(name)s')

Controller:
from gluon.tools import Crud
crud = Crud(db)

def index():
    form = SQLFORM(db.person)
    if form.process().accepted:
        response.flash = 'success'
    return dict(form=form)
    
def add_dog():    
    form = SQLFORM(db.dog)
    if form.process().accepted:
        response.flash = 'success'
    return dict(form=form)

def view():
    grid = SQLFORM.smartgrid(db.dog)
    grid2 = crud.select(db.person)
    return dict(grid=grid, grid2=grid2)

When I have the above code, a foreign key will be stored in the database, but all views of that key will be rendered as the numerical value of the foreign key, and not the name.  In the table definition, if I just have db.person instead of requires = IS_EMPTY_OR(IS_IN_DB(db,db.person)), It requires the field.  

Are there any workarounds?
-Joe Peacock

Anthony

unread,
Jul 17, 2012, 7:22:53 PM7/17/12
to web...@googlegroups.com
You should probably make it a reference field. By default, if you don't specify any "requires", you'll automatically get an IS_IN_DB validator as well as a "represent" attribute that displays whatever is specifying by the "format" attribute of the referenced table. However, if you specify your own validator(s), then you don't get any default "represent" -- so just add your own explicit represent:

db.define_table('dog',
   
Field('name'),
    Field('owner', db.person, requires=IS_EMPTY_OR(IS_IN_DB(db, 'person.id', '%(name)')),
          represent
=lambda id, row: db.person(id).name),
    format
= '%(name)s')

Anthony

joe

unread,
Jul 20, 2012, 3:47:33 PM7/20/12
to web...@googlegroups.com
That hasn't worked for me.  When I try, I get the error:

<type 'exceptions.KeyError'> 'name'


It points to the smartgrid I made, with this code:  grid = SQLFORM.smartgrid(db.dog)

Thanks!
-Joe Peacock

Anthony

unread,
Jul 20, 2012, 4:31:52 PM7/20/12
to web...@googlegroups.com
Oh, right, since you allow empty values, you'll need to test for that before doing the query:

represent=lambda id, row: db.person(id).name if id else 'Nobody owns this dog'

Anthony

Anthony

unread,
Jul 20, 2012, 4:37:11 PM7/20/12
to web...@googlegroups.com
Actually, I would think that would have caused an AttributeError (trying to access an attribute of a NoneType object). Not sure where the KeyError is arising.

Anthony

joe

unread,
Jul 23, 2012, 9:48:26 AM7/23/12
to web...@googlegroups.com
The key error was because it was '%(name)' not '%(name)s'.  Everything works now! Thanks!

Mandar Vaze

unread,
Aug 9, 2012, 12:20:08 AM8/9/12
to web...@googlegroups.com
I too am getting similar error (am using sqlform.grid, not smartgrid)
Waiting for feedback

Thanks,
-Mandar
Reply all
Reply to author
Forward
0 new messages