Can I first say that SQLFORM.grid is great and a massive productivity
gain, thanks Massimo & the rest of the web2py team.

My question is around formatting a column when the display value
depends on other non-visible columns (or other related tables).  We're
using the "links" parameter and a lambda function to generate the
label.  The clunky part is that the row function needs to go back to
the database each time as not all the fields required to generate that
display value are available in the "row" value passed to the lambda
function.  It seems like it would be cleaner if we didn't have to
unnecessarily revisit the database each time.

Here's a cut-back model & controller to illustrate.

db.define_table('fileimportgroup',
    Field('status', 'string'), # "not_started", "success",
"processing", "cancelled", "errors"
    Field('type', 'string'),
    Field('start', 'datetime'),
    Field('end', 'datetime'))

db.define_table('fileimportitem',
    Field('fileimportgroup_id', db.fileimportgroup),
    Field('status', 'string'), # "not_started", "unsupported_format",
"duplicate", "removed_prior_to_import", "failed", "imported"
    Field('processed', 'datetime'))

# Controller function
def importgroups():
    def _processing_status_label(fig):
        # This raises a KeyError unless db.fileimportgroup.status is
added in fields
        # status = fig.status

        # Have to select the status instead
        status =
db(db.fileimportgroup.id==fig['id']).select(db.fileimportgroup.status).first()
['status']

        fig_id = fig['id']
        if status == 'processing':
            total =
db(db.fileimportitem.fileimportgroup_id==fig_id).count()
            processed =
db((db.fileimportitem.fileimportgroup_id==fig_id)&
                (db.fileimportitem.status!='not_started')).count()
            return '%d/%d files processed' % (processed, total)
        if status == 'success':
            return 'Successful'
        # ... etc.
        return 'Unknown'

    links = [dict(header='Status', body=lambda row:
_processing_status_label(row))]
    grid=SQLFORM.grid((db.fileimportgroup.id>0), paginate=15,
            links=links, orderby=~db.fileimportgroup.start,
            fields=[db.fileimportgroup.start, db.fileimportgroup.end])

    return dict(importgroups=grid)


(I realise we could change the model and increment a processed count
on fileimportgroup, but I'm hoping for a recommended fix to the
general problem)

Can I suggest adding a new SQLFORM.grid parameter like
"fields_nonvisible" which would select these fields back from the
database but not add columns for them.  That would do the trick, does
that sound reasonable?

Or is there another way to achieve what we're doing without having to
select non "fields" values one at a time?  Thanks.

Reply via email to