Hello All,
I've used a SQLFORM.grid for displaying table content. I've provided export to CSV option in grid.
My app settings are as below:
models/db.py
db.define_table('company',
Field('name', 'string', length=128, notnull=True, unique=True),
Field('address', 'string'), format='%(name)s')
db.define_table('document',
Field('name', 'string', length=128, notnull=True),
Field('type', 'string', notnull=True),
Field('company', db.company, format='%(name)s')
Here,
document table has company as a reference key,
Exported CSV should contain the company names not ids
modules/doc_utils.py
from cStringIO import StringIO
class CSVExporter(object):
"""This class is used when grid's table contains reference key id.
Exported CSV should contain reference key name of reference
key not ids"""
file_ext = "csv"
content_type = "text/csv"
def __init__(self, rows):
self.rows = rows
def export(self):
if self.rows:
s = StringIO()
self.rows.export_to_csv_file(s, represent=True)
return s.getvalue()
else:
return ''
#Grid uses Custom search for string
def search_query(fields, keywords):
"""" Custom search for doc grid"""
if isinstance(keywords, (tuple, list)):
keywords = keywords[0]
request.vars.keywords = keywords
key = keywords.strip()
if key and not '"' in key and not "'" in key and key:
SEARCHABLE_TYPES = ('string', 'text', 'list:string')
words = key.split(' ') if key else []
filters = []
for field in fields:
#apply search on company_name also
#get db from current module
db = current.db
#get company name from record
if company_ids:
filters.append(field.belongs(company_ids))
continue
if field.type in SEARCHABLE_TYPES:
all_words_filters = []
for word in words:
all_words_filters.append(field.contains(word))
filters.append(reduce(lambda a, b: (a & b), all_words_filters))
parts = filters
else:
parts = None
if parts:
return reduce(lambda a, b: a | b, parts)
else:
return None
controllers/documents.py
from applications.asdf.doc_utils import CSVExporter, search_query
def docs():
export_csv = False
export_classes = None
query = valid_db_query_here
if auth.has_membership('manager'):
export_csv = True
export_classes = dict(csv=(CSVExporter, 'CSV'), xml=False, html=False,
json=False, csv_with_hidden_cols=False,
tsv=False, tsv_with_hidden_cols=False)
grid = SQLFORM.grid(query, orderby=~db.document.created_on,
showbuttontext=False, csv=export_csv, deletable=False,
searchable=search_query, exportclasses=export_classes)
return (grid=grid)
If I search single keyword like Google or MicroSoft in then export works as expected.
if I search multiple keywords like Google India Private Limited or Redhat India Pvt Ltd then it shows expected rows in grid
But If I click on export button then it gives me Following error
Ticket ID
127.0.0.1.2015-01-14.21-56-57.34fb2b60-2857-4c1a-9626-a854630fc9c7
<type 'exceptions.AttributeError'> 'list' object has no attribute 'colnames'
Version
web2py™ Version 2.9.5-stable+timestamp.2014.03.16.02.35.39
Traceback
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Traceback (most recent call last):
File "/home/prasad/Rootpy/web2py_2.9/gluon/restricted.py", line 220, in restricted
exec ccode in environment
File "/home/prasad/Rootpy/web2py_2.9/applications/asdf/controllers/documents.py", line 137, in <module>
File "/home/prasad/Rootpy/web2py_2.9/gluon/globals.py", line 385, in <lambda>
self._caller = lambda f: f()
File "/home/prasad/Rootpy/web2py_2.9/gluon/tools.py", line 3287, in f
return action(*a, **b)
File "/home/prasad/Rootpy/web2py_2.9/gluon/tools.py", line 3287, in f
return action(*a, **b)
File "/home/prasad/Rootpy/web2py_2.9/applications/asdf/controllers/documents.py", line 112, in upload
exportclasses=export_classes)
File "/home/prasad/Rootpy/web2py_2.9/gluon/sqlhtml.py", line 2221, in grid
rows.colnames = expcolumns # expcolumns is all cols to be exported including virtual fields
AttributeError: 'list' object has no attribute 'colnames'
I've started debugging and got following the point.
For single keyword search, the rows object has <class 'gluon.dal.Rows'> type and it contains exact rows which query gives
But the rows object has list type for multiple search keywords
Any clues/hints/suggestions for debugging this error?