Method for applying "represent" attributes to rows

196 views
Skip to first unread message

Anthony

unread,
Jun 20, 2013, 11:04:37 PM6/20/13
to
How about adding the method below to the DAL Rows class? It allows transformation of values within a Row based on the "represent" attributes of the fields:

rows = db(query).select()
repr_row
= rows.repr(0)

If you don't specify an index, you get a generator to iterate over all the rows:

for row in rows.repr():
   
print row.myfield

Can also be applied to slices:

for row in rows[0:10].repr():
   
print row.myfield

If you only want to transform selected fields via their "represent" attribute, you can list them in the "fields" argument:

repr_row = row.repr(0, fields=[db.mytable.myfield])

Note, it returns a transformed copy of the original Row, so there's no update_record (which you wouldn't want anyway) or delete_record.

Thoughts? Here's the code:

    def repr(self, i=None, fields=None):
       
"""
        Takes an index and returns a copy of the indexed row with values
        transformed via the "
represent" attributes of the associated fields.
       
        If no index is specified, a generator is returned for iteration
        over all the rows.
       
        fields -- a list of fields to transform (if None, all fields with
                  "
represent" attributes will be transformed).
        """



       
if i is None:
           
return (self.repr(i, fields=fields) for i in range(len(self)))
       
import sqlhtml
        row
= copy.copy(self.records[i])
        keys
= row.keys()
        tables
= [f.tablename for f in fields] if fields \
                 
else [k for k in keys if k != '_extra']
       
for table in tables:
            repr_fields
= [f.name for f in fields] if fields \
                         
else [k for k in row[table].keys()
                               
if (hasattr(self.db[table], k) and
                                isinstance
(self.db[table][k], Field)
                               
and self.db[table][k].represent)]
           
for field in repr_fields:
                row
[table][field] = sqlhtml.represent(self.db[table][field],
                    row
[table][field], row[table])
       
if self.compact and len(keys) == 1 and keys[0] != '_extra':
           
return row[keys[0]]
       
return row


Anthony

Anthony

unread,
Jun 20, 2013, 11:24:39 PM6/20/13
to web2py-d...@googlegroups.com
Oops, small fix in code below:

    def repr(self, i=None, fields=None):
       
"""
        Takes an index and returns a copy of the indexed row with values
        transformed via the "
represent" attributes of the associated fields.
       
        If no index is specified, a generator is returned for iteration
        over all the rows.
       
        fields -- a list of fields to transform (if None, all fields with
                  "
represent" attributes will be transformed).
        """



       
if i is None:
           
return (self.repr(i, fields=fields) for i in range(len(self)))
       
import sqlhtml
        row
= copy.copy(self.records[i])
        keys
= row.keys()
        tables
= [f.tablename for f in fields] if fields \
                 
else [k for k in keys if k != '_extra']
       
for table in tables:

            repr_fields
= [f.name for f in fields if f.tablename == table] if fields \

                         
else [k for k in row[table].keys()
                               
if (hasattr(self.db[table], k) and
                                isinstance
(self.db[table][k], Field)
                               
and self.db[table][k].represent)]
           
for field in repr_fields:
                row
[table][field] = sqlhtml.represent(self.db[table][field],
                    row
[table][field], row[table])
       
if self.compact and len(keys) == 1 and keys[0] != '_extra':
           
return row[keys[0]]
       
return row


Anthony

Massimo DiPierro

unread,
Jun 21, 2013, 2:52:00 AM6/21/13
to web2py-d...@googlegroups.com
I like it! In trunk. :-)



--
-- mail from:GoogleGroups "web2py-developers" mailing list
make speech: web2py-d...@googlegroups.com
unsubscribe: web2py-develop...@googlegroups.com
details : http://groups.google.com/group/web2py-developers
the project: http://code.google.com/p/web2py/
official : http://www.web2py.com/
---
You received this message because you are subscribed to the Google Groups "web2py-developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py-develop...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Alan Etkin

unread,
Jun 21, 2013, 7:12:50 AM6/21/13
to
El viernes, 21 de junio de 2013 03:52:00 UTC-3, Massimo Di Pierro escribió:
I like it! In trunk. :-)

Is this ok (or should they return the same)?

>>> repr(rows)
'<Rows (3)>'
>>> rows.repr()
<generator object <genexpr> at 0xa86ea04>

EDIT: Perhaps it would be less confusing if the new method was named Rows.represent

Massimo DiPierro

unread,
Jun 21, 2013, 7:47:01 AM6/21/13
to web2py-d...@googlegroups.com
This is ok because

repr(rows) is the same as rows.__repr__() not of rows.repr() Yet the latter should be renamed to avoid confusion. Suggestions for a better name? "represent" perhaps?

On Jun 21, 2013, at 6:04 AM, Alan Etkin wrote:

El viernes, 21 de junio de 2013 03:52:00 UTC-3, Massimo Di Pierro escribió:
I like it! In trunk. :-)

Is this ok (or should they return the same)?

>>> repr(rows)
'<Rows (3)>'
>>> rows.repr()
<generator object <genexpr> at 0xa86ea04>



Anthony

unread,
Jun 21, 2013, 11:01:12 AM6/21/13
to web2py-d...@googlegroups.com
I thought about this and opted for .repr() just to keep it shorter. I was also concerned that rows.represent() might be confused with db.mytable.myfield.represent() (the former uses the latter, but they have different signatures). Perhaps there is a third alternative, though I haven't thought of a good one yet. Anyway, I wouldn't object to rows.represent() if everyone prefers that.

Anthony

Massimo DiPierro

unread,
Jun 26, 2013, 4:10:16 AM6/26/13
to web2py-d...@googlegroups.com
So.... this is in but I think we need a better name. Suggestions?

On Jun 20, 2013, at 10:24 PM, Anthony wrote:

Niphlod

unread,
Jun 26, 2013, 4:45:55 AM6/26/13
to web2py-d...@googlegroups.com
render ?

Anthony

unread,
Jul 2, 2013, 11:57:58 PM7/2/13
to
OK, here are some options for the name:

rows.repr()
rows
.represent()
rows
.repr_fields()
rows
.field_repr()
rows
.render()
rows
.display()

Another option might be to use the __call__ method and generalize it to return a copy of a row, optionally (and by default) transformed via the "represent" attributes of its fields. So, you would do:

row_copy = rows(1)  # uses the "represent" attributes by default
row_copy
= rows(1, represent_fields=False)  # just a plain copy -- no represent used
row_copy
= rows(1, represent_fields=[db.mytable.myfield1, db.mytable.myfield2])  # represent specific fields
for row_copy in rows():  # iterate through all the rows

Here's the code for the __call__ method (note, this also fixes a couple problems with the original method, such as doing a deepcopy instead of a copy):

    def __call__(self, i=None, represent_fields=True):
       
"""
        Takes an index and returns a copy of the indexed row, by default
        transforming each value via the "
represent" attribute of the
        associated fields.
        
        If no index is specified, a generator is returned for iteration
        over all the rows.

        :represent_fields (defaults to True): indicates field values are to be
            transformed via their "
represent" attributes. Can also be a list of
            specific fields to transform.

        """


       
if i is None:
           
return (self.__call__(i, represent_fields=represent_fields)

                   
for i in range(len(self)))
       
import
sqlhtml
        row
= copy.deepcopy(self.records[i])
        keys
= row.keys()
       
if represent_fields:
            field_list
= isinstance(represent_fields, (list, tuple))
            tables
= [f.tablename for f in represent_fields] if field_list \

                     
else [k for k in keys if k != '_extra']
           
for table in tables:

               
if field_list:
                    fields
= [f.name for f in represent_fields
                             
if f in self.db[table].fields]
               
else:
                    fields
= [k for k in row[table].keys()

                             
if (hasattr(self.db[table], k)
                             
and isinstance(self.db[table][k], Field)
                             
and self.db[table][k].represent)]

               
for field in fields:

                    row
[table][field] = sqlhtml.represent(self.db[table][field],
                        row
[table][field], row[table])
       
if self.compact and len(keys) == 1 and keys[0] != '_extra':
           
return row[keys[0]]
       
return row

Anthony

Massimo DiPierro

unread,
Jul 3, 2013, 2:49:00 AM7/3/13
to web2py-d...@googlegroups.com
I like

rows.render()

On Jul 2, 2013, at 10:56 PM, Anthony wrote:

OK, here are some options for the name:

rows.repr()
rows
.represent()
rows
.repr_fields()
rows
.field_repr()
rows
.render()
rows
.display()

Another option might be to use the __call__ method and generalize it to return a copy of a row, optionally (and by default) transformed via the "represent" attributes of its fields. So, you would do:

row_copy = rows(1)  # uses the "represent" attributes by default
row_copy
= rows(1, represent_fields=False)  # just a plain copy -- no represent used
row_copy
= rows(1, represent_fields=[db.mytable.myfield1, db.mytable.myfield2])  # represent specific fields
for row_copy in rows():  # iterate through all the rows

Here's the code for the __call__ method (note, this also fixes a couple problems with the original method, such as doing a deepcopy instead of a copy):

    def __call__(self, i=None, represent_fields=True):
       
"""

        Takes an index and returns a copy of the indexed row, by default
        transforming each value via the "represent" attribute of the

        associated fields.
       
        If no index is specified, a generator is returned for iteration
        over all the rows.

        :represent_fields (defaults to True): indicates field values are to be
            transformed via their "
represent" attributes. Can also be a list of
            specific fields to transform.

        """


       
if i is None:
           
return (self.__call__(i, represent_fields=represent_fields)

                   
for i in range(len(self)))
       
import
sqlhtml
        row
= copy.deepcopy(self.records[i])
        keys
= row.keys()

       
if represent_fields:
            field_list
= isinstance(represent_fields, (list, tuple))

            tables
= [f.tablename for f in represent_fields] if field_list \

                     
else [k for k in keys if k != '_extra']
           
for table in tables:

               
if field_list:
                    fields
= [f.name for f in represent_fields
                             
if f in self.db[table].fields]
               
else:

                    fields
= [k for k in row[table].keys()

                             
if (hasattr(self.db[table], k)
                             
and isinstance(self.db[table][k], Field)
                             
and self.db[table][k].represent)]

               
for field in fields:

                    row
[table][field] = sqlhtml.represent(self.db[table][field],
                        row
[table][field], row[table])
       
if self.compact and len(keys) == 1 and keys[0] != '_extra':
           
return row[keys[0]]
       
return row

Anthony

On Wednesday, June 26, 2013 4:45:55 AM UTC-4, Niphlod wrote:

Anthony

unread,
Jul 3, 2013, 9:36:44 AM7/3/13
to web2py-d...@googlegroups.com
Don't like the __call__ idea?
 
.render() seems OK, but I thought it might imply that the entire row would be rendered to an HTML structure. I was thinking maybe something like .display() might be less confusing.
 
Anthony

Alan Etkin

unread,
Jul 3, 2013, 1:07:23 PM7/3/13
to web2py-d...@googlegroups.com
Don't like the __call__ idea?
 
.render() seems OK, but I thought it might imply that the entire row would be rendered to an HTML structure. I was thinking maybe something like .display() might be less confusing.

I'd use Rows.represent and would clarify the difference everywhere needed (book, docstrings). IMO It's not expect that a Rows object supports assignment as with the Field class nor override the Field class represent settings.

Anthony

unread,
Jul 3, 2013, 2:28:48 PM7/3/13
to web2py-d...@googlegroups.com

I'd use Rows.represent and would clarify the difference everywhere needed (book, docstrings). IMO It's not expect that a Rows object supports assignment as with the Field class nor override the Field class represent settings.

What do you mean by "assignment" and overriding the represent settings?

Anthony 

Alan Etkin

unread,
Jul 3, 2013, 3:52:14 PM7/3/13
to web2py-d...@googlegroups.com
What do you mean by "assignment" and overriding the represent settings?

I meant that I don't expect a Rows class object to allow me to do:

rows.represent = lambda name, row: ...

and that shouldn't be necessary to set that attribute to override the field representation set with

db.mytable.myfield.represent = lambda ...

for the specific rows render, since it would be possible to set db.mytable.myfield.represent temporarily instead.

But if the Rows class is going to support something like

rows.represent = {"myfield": lambda value, row: ..., "otherfield": ...}

then it's not possible to change the Row.repr method name to Row.represent

Anthony

unread,
Jul 3, 2013, 4:45:57 PM7/3/13
to web2py-d...@googlegroups.com
I see. Yeah, I think my favorites so far are rows.represent() and rows.display().

Anthony

Massimo DiPierro

unread,
Jul 3, 2013, 4:55:36 PM7/3/13
to web2py-d...@googlegroups.com
I just committed rows.render() although this is not be the final word about it.

Richard Vézina

unread,
Aug 21, 2013, 10:39:50 AM8/21/13
to web2py-d...@googlegroups.com
Is the utility of this to allow access or create a representation of a record in case of construction of a custom table (TABLE(...))??

I need badly a way to set the representation of the record in a custom table, I may just don't know how to do it though.

Thanks

Richard
Reply all
Reply to author
Forward
0 new messages