Add generic support for downloading list results as CSV
This commit is contained in:
parent
f6d9f7a913
commit
9ff6df83e5
|
@ -69,6 +69,9 @@
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="context_menu_items()">
|
<%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)):
|
% 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>
|
<li>${h.link_to("Create a new {}".format(model_title), url('{}.create'.format(route_prefix)))}</li>
|
||||||
% endif
|
% endif
|
||||||
|
|
|
@ -40,6 +40,7 @@ from rattail.db.continuum import model_transaction_query
|
||||||
from rattail.util import prettify
|
from rattail.util import prettify
|
||||||
from rattail.time import localtime #, make_utc
|
from rattail.time import localtime #, make_utc
|
||||||
from rattail.threads import Thread
|
from rattail.threads import Thread
|
||||||
|
from rattail.csvutil import UnicodeDictWriter
|
||||||
|
|
||||||
import formalchemy as fa
|
import formalchemy as fa
|
||||||
from pyramid import httpexceptions
|
from pyramid import httpexceptions
|
||||||
|
@ -64,6 +65,7 @@ class MasterView(View):
|
||||||
checkboxes = False
|
checkboxes = False
|
||||||
|
|
||||||
listable = True
|
listable = True
|
||||||
|
results_downloadable_csv = False
|
||||||
creatable = True
|
creatable = True
|
||||||
viewable = True
|
viewable = True
|
||||||
editable = True
|
editable = True
|
||||||
|
@ -1384,6 +1386,46 @@ class MasterView(View):
|
||||||
"""
|
"""
|
||||||
return False
|
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
|
# CRUD Stuff
|
||||||
##############################
|
##############################
|
||||||
|
@ -1799,6 +1841,14 @@ class MasterView(View):
|
||||||
config.add_view(cls, attr='mobile_index', route_name='mobile.{}'.format(route_prefix),
|
config.add_view(cls, attr='mobile_index', route_name='mobile.{}'.format(route_prefix),
|
||||||
permission='{}.list'.format(permission_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
|
# create
|
||||||
if cls.creatable or cls.mobile_creatable:
|
if cls.creatable or cls.mobile_creatable:
|
||||||
config.add_tailbone_permission(permission_prefix, '{}.create'.format(permission_prefix),
|
config.add_tailbone_permission(permission_prefix, '{}.create'.format(permission_prefix),
|
||||||
|
|
Loading…
Reference in a new issue