Hello,
Can you please help me with the following. I work with web2py for a few days. I have a table of products (name, description, unit_price) and orders (product, quantity).
I want to show the orders in a grid with an additionnal column "Total" which is order.quantity * product.unit_price.
I use then a query that makes a join between the tables order and product, and use the links argument to add the Total column.
In the model:
<pre>
db.define_table('t_product',
Field('f_name', type='string',
label=T('Name'), required=True),
Field('f_description', type='text',
label=T('Description')),
Field('f_unit_price', type='double',
label=T('Price'), required=True)
)
db.define_table('t_order',
Field('f_product_id', type='reference t_product',
label=T('Product')),
Field('f_quantity', type='integer',
label=T('Quantity'))
)
</pre>
In the controller:
<pre>
query = ((db.t_order.modified_by==auth.user_id) & (db.t_order.f_product_id==
db.t_product.id))
fields = (db.t_product.f_name, db.t_product.f_unit_price, db.t_order.f_quantity)
links = [dict(header=T("Total price"), body=lambda row: row.t_order.f_quantity*row.t_product.f_unit_price)]
grid = SQLFORM.grid(query=query, args=request.args[:1],
fields=fields, headers=headers,
orderby=default_sort_order, links=links,
create=True, deletable=True, editable=True,
csv=False, searchable=False, details=True,
maxtextlength=64, paginate=25, showbuttontext=False)
</pre>
The first display of the grid is OK: I can see the additionnal column.
However I have the following issue when clicking on the "details", "edit" or "delete" button:
<pre>AttributeError: 'Row' object has no attribute 't_order'</pre>
The current workaround is to test in the lambda code if the Row object has a t_order attribute thus:
<pre>lambda row: (row.t_item.f_quantity*row.t_product.f_unit_price) if hasattr(row, "t_item") else ""</pre>
I have to return an empty string because this is what is shown in the detail/edit form
It seems that when clicking on the detail/edit/delete button, the row passed to the lambda function is no more a row in the resulting join, hence we can no more access a field with row.table.fieldname but with row.fieldname
In my opinion my first implementation is logic and should be the way to do it.
Am I missing something?
Thanks.
Kind regards,
Frederic F. MONFILS