appadmin.py interpret represent differently than default.py, causing keyError or attributeError

25 views
Skip to first unread message

Yi Liu

unread,
Feb 1, 2018, 9:39:37 PM2/1/18
to web2py-users
Dear all,

I have a field with custom represent:
```
Field('f_lastupdate', type='string',
          label=T('Last Update'), represent=lambda value, row: lastUpdateDateFormat(value, row['t_trial']['f_ctid'])),
```

It is fine in the application (default.py), but not in appadmin when i admin the table.

If i change row['t_trial']['f_ctid'] to row['f_ctid'], appadmin works but the application throws similar error. It seems appadmin.py interpret the lambda function differently than default.py, causing keyerror or attributeerror

Am I missing something? Thanks!

Yi Liu

unread,
Feb 1, 2018, 11:23:41 PM2/1/18
to web2py-users
I figured a work around:

```
if request.controller == 'default':
        ctID = ctID.t_trial.f_ctid
    else:
        ctID = ctID.f_ctid
```

It would be nice to fix from the source.

Anthony

unread,
Feb 2, 2018, 7:29:17 AM2/2/18
to web2py-users
On Thursday, February 1, 2018 at 11:23:41 PM UTC-5, Yi Liu wrote:
I figured a work around:

```
if request.controller == 'default':
        ctID = ctID.t_trial.f_ctid
    else:
        ctID = ctID.f_ctid
```

It would be nice to fix from the source.

There is nothing to be done in appadmin.py -- it simply passes data to appadmin.html, which ultimately calls SQLTABLE. SQLTABLE itself simply passes the field's value and the record containing the value to the represent function -- it does not and cannot "interpret" the represent function -- it is up to you to write a represent function that works with the values that will be passed in.

In this case, the difference in behavior between appadmin and your controller is likely due to the fact that you are doing a join in the controller (the selects in appadmin do not involve joins). Without a join, values are referenced as row.fieldname, but with a join, you must use row.tablename.fieldname. If you need your "represent" function to accommodate both cases, then you must code it appropriately:

represent=lambda value, row: lastUpdateDateFormat(value, row.get('f_ctid', row.t_trial.f_ctid))

The above first attempts to get row.f_ctid, and if the "f_ctid" key does not exist on the row object (which would be the case when doing a join, unless the join also happens to include a table named "f_ctid"), it then uses the value row.t_trial.f_ctid.

Anthony

Yi Liu

unread,
Feb 2, 2018, 9:56:47 AM2/2/18
to web2py-users
Thank you so much for your detailed explanation. You also solved my puzzle about the behavior of join tables. Amazing that you know I have join tables in default.py when I didn’t say it. Lol.

Really appreciate your help.
Reply all
Reply to author
Forward
0 new messages