I am trying to use the CascadingSelect available here, but get <type 'exceptions.KeyError'>
. My models are as below:
# -*- coding: utf-8 -*-
db.define_table('bank_master',
Field('name'),
format='%(name)s'
)
db.define_table('bank_branch',
Field('bank', db.bank_master),
Field('name'),
format='%(name)s'
)
db.define_table('case_master',
Field('case_number'),
Field('bank_branch', db.bank_branch)
)
if db(db.bank_master.id>0).count() == 0:
db.bank_master.truncate()
db.bank_branch.truncate()
db.bank_master.insert(name='State Bank')
db.bank_master.insert(name='Central Bank')
db.bank_master.insert(name='Canara Bank')
db.bank_branch.insert(name='Austin',bank=1)
db.bank_branch.insert(name='Dallas',bank=1)
db.bank_branch.insert(name='Chicago',bank=2)
db.bank_branch.insert(name='Washington',bank=2)
db.bank_branch.insert(name='Florida',bank=3)
db.bank_branch.insert(name='Delhi',bank=3)
cascade = CascadingSelect(db.bank_master,db.bank_branch)
db.case_master.bank_branch.widget = cascade.widget
This is the controller:
def index():
form = SQLFORM(db.case_master)
return dict(form=form)
And this is the view index.html
:
{{extend 'layout.html'}}
<h1>Test for Cascade</h1>
<h3>{{=form}}</h3>
This is the error ticket:
Traceback (most recent call last):
File "C:\web2py\gluon\restricted.py", line 219, in restricted
exec(ccode, environment)
File "C:/web2py/applications/cascade_3/controllers/default.py", line 64, in <module>
File "C:\web2py\gluon\globals.py", line 419, in <lambda>
self._caller = lambda f: f()
File "C:/web2py/applications/cascade_3/controllers/default.py", line 9, in index
form = SQLFORM(db.case_master)
File "C:\web2py\gluon\sqlhtml.py", line 1505, in __init__
inp = field.widget(field, default)
File "C:/web2py/applications/cascade_3/models/cascade_widget.py", line 26, in widget
for opt in options]
File "C:\web2py\gluon\packages\dal\pydal\objects.py", line 96, in __getitem__
raise KeyError
KeyError
The CascadingSelect widget works perfectly when the models used by mfreeze is tweaked by adding dummy fields, but somehow when I use my own models as above, the KeyError
crops up. Can anyone help in locating my error?
The code for the CascadingSelect
widget includes the following:
opts = [OPTION(format % opt,_value=opt.id,
_parent=opt[str(parent)] if parent else '0') \
for opt in options]
The KeyError
is the result of opt[str(parent)]
on the second pass through the for
loop. In that case, opt
is a Row
from the db.bank_branch
table, and the value of str(parent)
is "bank_master"
(i.e., the name of the first table). The value of parent
is set near the end of the for
loop at:
parent = table
Of course, there is no bank_master
field in db.bank_branch
(instead, the reference field is simply named "bank"
). So, the widget code expects the name of the reference field in the second table to be the same as the name of the first table. In other words, instead of:
Field('bank', db.bank_master)
it expects:
Field('bank_master', db.bank_master)
which is a common convention when naming reference fields in web2py.
So, you can either rename the reference field so it works with the current widget code, or you can modify the code to accommodate alternative reference field names (probably by adding an argument allowing you to specify the name explicitly).