Changing links on SQLTABLE

73 views
Skip to first unread message

weheh

unread,
Apr 20, 2009, 2:39:29 AM4/20/09
to web2py Web Framework
I know this issue has been kicked around alot already and I've
searched the posts for the answer, but I haven't been able to figure
out the way to do the following.

I'm using SQLTABLE with a linkto attribute, which creates a link on
the id field. I would prefer to hide the ID field and move the same id
link to one or more of the other SQLTABLE fields. I've tried doing
this with a lambda function but I can't seem to get it to work. Does
anyone have an example of this, please? Thx.

SergeyPo

unread,
Apr 20, 2009, 2:57:55 AM4/20/09
to web2py Web Framework
It's my specialty in this forum to give link to a thread for SQLTABLE
personalizing.
SQLTTABLE looks like one of the biggest attractors of the whole
web2py, so some effort for extra features and documentation is
required.
Lambda function example and another home-made method is described
here: http://groups.google.com/group/web2py/browse_thread/thread/a0c789cccafe8014/f1f96197a13cfeb7?show_docid=f1f96197a13cfeb7

weheh

unread,
Apr 20, 2009, 3:49:12 AM4/20/09
to web2py Web Framework
SergeyPo - Many thanks to you for your earlier post with which I am
already intimately familiar. I've been able to follow the advice from
that post successfully in many other cases.

However, I can't seem to figure out how to write a lambda statement
that duplicates the link that web2py/gluon auto-creates for the id
field. I then want to apply that href to any or all other field in the
SQLTABLE for the purposes of making the entire row and all fields and
entries in that row a giant link to that record.

I've tried something like this but it doesn't work:

db.table.name.represent = lambda row: A(_href=URL
(r=request,f='action',args=db(db.table.id==row.id).select
(db.table.id)))

I don't know how to reference the id field while talking about the
name field.

SergeyPo

unread,
Apr 20, 2009, 4:34:38 AM4/20/09
to web2py Web Framework
Sorry Weheh, did not recognize you :)
You can not achieve desied effect with lambda for represent because
lambda does not get enough information: try
db.table.name.represent = lambda o: type(o)
and you will see that lambda gets str datatype as parameter, so all
links to SQLRow etc. are lost.
You can use my update_column function, but for entire rows that will
look too ugly and take too many lines of code. I think, this is the
case when it's easier to write your own code to generate table just
like you want. Something like:

rs = db(condition).select()
for row in rs:
current_id = str(row.id)
table.append(TR(''' add columns ''',
_onclick="javascript:document.location = 'blah/blah' + current_id"))

Bruno Rocha

unread,
Dec 8, 2010, 11:13:49 PM12/8/10
to web...@googlegroups.com
I Know this is an VERY OLD post, but I was searching the group and I now have the same need as weheh in this thread.

db.define_table('person',
                      Field('name'),
                      Field('city'),
                      Field('state'),
                      Field('email',represent: lambda row: A(_href=URL('changemail',vars=dict(person_id=row.id))))
                      )

But, lambda in this case is getting row as str() with the mail adress stored in 'email' field, I need to have the row id.

another easy way?


I am thinking about override the SQLTABLE class to include this kind of option if I can't find an easy solution.


mdipierro

unread,
Dec 9, 2010, 12:19:52 AM12/9/10
to web2py-users
Sorry. Cannot be done this way. Represent takes the field value, not
the entire row.
The reason is that when web2py tries to represent a field in a
SQLTABLE or in a FORM, only that field is guaranteed to be there. the
other fields may not have been fetched from the database.

Anyway... I will think this can be improved.
Let us know if you have any idea.

Massimo

Bruno Rocha

unread,
Dec 9, 2010, 12:58:12 AM12/9/10
to web...@googlegroups.com
I am overriding SQLTABLE class, here is my idea, let me know if this is a stupid idea :P

I want to pass to SQLTABLE a represent_dictionary which I call 'rd', so if I have a table:

<table>
db.define_table('person',
                      Field('name'),
                      Field('city'),
                      Field('state'),
                      Field('email')
                      )
</table>

My rd will be:

<code>
rd = dict(person.email={'repr_string':A(_href=URL('changemail',vars=dict(person_id='%s'))),
                                   'fetch':'person.id'})

# I want to pass rd to SQLTABLE

<code>
mytable = SQLTABLE(Rows,rd=rd)
</code>

Now in SQLTABLE for each column name, I will check if there is a entry for this key in 'rd', if True:

<code>
for i,row in enumerate(sqlrows):
    field.represent = rd[columnname]['repr_string'] % row[rd['fetch']]
</code>


This way, I can always pass a dict containing a string with placeholders to override the represent for any column in the table, and this dict will contains which column value will be fetched for every row.

I am making some tests, I just need a way to include some html tags including another field values, as ID for every column.

Is that a stupid idea? :P

Thanks





epresent: lambda row: 


2010/12/9 mdipierro <mdip...@cs.depaul.edu>

mdipierro

unread,
Dec 9, 2010, 1:29:27 AM12/9/10
to web2py-users
Other options:

1)

db.table.field.represent=lambda row='row': ...

if field.represent.func_defaults[0]=='row': ...


2)

db.table.field.represent=lambda row={}: ...

if isinstance(field.represent.func_defaults[0],dict): ...

3)

if field.represent.func_code.co_varnames[0]=='row': ...





this is used in SQLTABLE, FIELD, crud.read, crud.update.

Massimo
> 2010/12/9 mdipierro <mdipie...@cs.depaul.edu>

Bruno Rocha

unread,
Dec 9, 2010, 12:45:55 PM12/9/10
to web...@googlegroups.com
I think I do not understant your options very well,

but now I am working on the way I mentioned.

My SQLTABLE receives a parameter called rd (represent dictionary) and I can pass any string with placeholders and fields to fetch the value.

I dont want to change the 'represent' at the model level, because I need different represent to forms and tables,
I think it is better to define an exclusive represent dictionary to use in SQLTABLE that do not affects the representation in forms.

I will create a slice as soon as I finish that.

2010/12/9 mdipierro <mdip...@cs.depaul.edu>

Ivan Matveev

unread,
Dec 9, 2010, 3:51:56 PM12/9/10
to web...@googlegroups.com
You can put anything in SQLTABLE by modifying Rows object with
rows.setvirtualfields.
See this post
http://groups.google.com/group/web2py/browse_thread/thread/826a37f56c26d689

Bruno Rocha

unread,
Dec 9, 2010, 5:00:35 PM12/9/10
to web...@googlegroups.com
This:

<code>
class ExtraField: 
    def new_column(self): 
        if self.task.id==1: 
            return A('some_action_link',
                     _href=URL(f='default',
                               args=[self.task.id]))  
        else: 
            return A('great thing', _href='http://www.web2py.com') 


def test():
    rows=db(db.task).select() 
    rows.colnames.append('task.new_column') 
    rows.setvirtualfields(task=ExtraField()) 
    table=SQLTABLE(rows)
    return dict(table=table)

</code>

Is not working raising this error:

Traceback (most recent call last):
File "/Users/brunomac/web2py/gluon/restricted.py", line 188, in restricted
exec ccode in environment
File "/Users/brunomac/web2py/applications/satlite/controllers/teste.py", line 71, in <module>
File "/Users/brunomac/web2py/gluon/globals.py", line 96, in <lambda>
self._caller = lambda f: f()
File "/Users/brunomac/web2py/applications/satlite/controllers/teste.py", line 20, in test
table=SQLTABLE(rows)
File "/Users/brunomac/web2py/gluon/sqlhtml.py", line 1241, in __init__
File "/Users/brunomac/web2py/gluon/sql.py", line 3787, in __str__
self.export_to_csv_file(s)
File "/Users/brunomac/web2py/gluon/sql.py", line 3771, in export_to_csv_file
field = self.db[t][f]
File "/Users/brunomac/web2py/gluon/sql.py", line 1668, in __getitem__
return dict.__getitem__(self, str(key))
KeyError: 'new_column'



2010/12/9 Ivan Matveev <imatv...@gmail.com>

Bruno Rocha

unread,
Dec 9, 2010, 5:05:02 PM12/9/10
to web...@googlegroups.com
Note that when I do:

print sqlrows.colnames in sqlhtml.py I get:

['task.id', 'task.title', 'task.story', 'task.type', 'task.body', 'task.priority', 'task.assigned_to', 'task.estimated_hours', 'task.spent_hours', 'task.status', 'task.created_on', 'task.created_by', 'task.updated_on', 'task.updated_by', 'task.new_column']

2010/12/9 Bruno Rocha <rocha...@gmail.com>

Bruno Rocha

unread,
Dec 9, 2010, 5:44:39 PM12/9/10
to web...@googlegroups.com
I just got it! the problem is in definition of headers, when headers=None this works well.

I am going to patch for this.

2010/12/9 Bruno Rocha <rocha...@gmail.com>
Reply all
Reply to author
Forward
0 new messages