Add generic support for downloading list results as CSV
This commit is contained in:
parent
f6d9f7a913
commit
9ff6df83e5
|
@ -69,6 +69,9 @@
|
|||
</%def>
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
% if master.results_downloadable_csv and request.has_perm('{}.results_csv'.format(permission_prefix)):
|
||||
<li>${h.link_to("Download results as CSV", url('{}.results_csv'.format(route_prefix)))}</li>
|
||||
% endif
|
||||
% if master.creatable and request.has_perm('{}.create'.format(permission_prefix)):
|
||||
<li>${h.link_to("Create a new {}".format(model_title), url('{}.create'.format(route_prefix)))}</li>
|
||||
% endif
|
||||
|
|
|
@ -40,6 +40,7 @@ from rattail.db.continuum import model_transaction_query
|
|||
from rattail.util import prettify
|
||||
from rattail.time import localtime #, make_utc
|
||||
from rattail.threads import Thread
|
||||
from rattail.csvutil import UnicodeDictWriter
|
||||
|
||||
import formalchemy as fa
|
||||
from pyramid import httpexceptions
|
||||
|
@ -64,6 +65,7 @@ class MasterView(View):
|
|||
checkboxes = False
|
||||
|
||||
listable = True
|
||||
results_downloadable_csv = False
|
||||
creatable = True
|
||||
viewable = True
|
||||
editable = True
|
||||
|
@ -1384,6 +1386,46 @@ class MasterView(View):
|
|||
"""
|
||||
return False
|
||||
|
||||
def results_csv(self):
|
||||
"""
|
||||
Download current list results as CSV
|
||||
"""
|
||||
results = self.get_effective_data()
|
||||
fields = self.get_csv_fields()
|
||||
data = six.StringIO()
|
||||
writer = UnicodeDictWriter(data, fields)
|
||||
writer.writeheader()
|
||||
for obj in results:
|
||||
writer.writerow(self.get_csv_row(obj, fields))
|
||||
response = self.request.response
|
||||
response.text = data.getvalue().decode('utf_8')
|
||||
data.close()
|
||||
response.content_length = len(response.text)
|
||||
response.content_type = b'text/csv'
|
||||
response.content_disposition = b'attachment; filename={}.csv'.format(self.get_grid_key())
|
||||
return response
|
||||
|
||||
def get_csv_fields(self):
|
||||
"""
|
||||
Return the list of fields to be written to CSV download.
|
||||
"""
|
||||
fields = []
|
||||
mapper = orm.class_mapper(self.model_class)
|
||||
for prop in mapper.iterate_properties:
|
||||
if isinstance(prop, orm.ColumnProperty):
|
||||
fields.append(prop.key)
|
||||
return fields
|
||||
|
||||
def get_csv_row(self, obj, fields):
|
||||
"""
|
||||
Return a dict for use when writing the row's data to CSV download.
|
||||
"""
|
||||
csvrow = {}
|
||||
for field in fields:
|
||||
value = getattr(obj, field)
|
||||
csvrow[field] = '' if value is None else six.text_type(value)
|
||||
return csvrow
|
||||
|
||||
##############################
|
||||
# CRUD Stuff
|
||||
##############################
|
||||
|
@ -1799,6 +1841,14 @@ class MasterView(View):
|
|||
config.add_view(cls, attr='mobile_index', route_name='mobile.{}'.format(route_prefix),
|
||||
permission='{}.list'.format(permission_prefix))
|
||||
|
||||
if cls.results_downloadable_csv:
|
||||
config.add_tailbone_permission(permission_prefix, '{}.results_csv'.format(permission_prefix),
|
||||
"Download {} as CSV".format(model_title_plural))
|
||||
config.add_route('{}.results_csv'.format(route_prefix), '{}/csv'.format(url_prefix))
|
||||
config.add_view(cls, attr='results_csv', route_name='{}.results_csv'.format(route_prefix),
|
||||
permission='{}.results_csv'.format(permission_prefix))
|
||||
|
||||
|
||||
# create
|
||||
if cls.creatable or cls.mobile_creatable:
|
||||
config.add_tailbone_permission(permission_prefix, '{}.create'.format(permission_prefix),
|
||||
|
|
Loading…
Reference in a new issue