Add "download row results as CSV" feature to master view

This commit is contained in:
Lance Edgar 2017-10-14 14:14:24 -07:00
parent f338a03c97
commit c95e2dbb06
5 changed files with 67 additions and 53 deletions

View file

@ -37,7 +37,6 @@ from sqlalchemy import orm
from rattail.db import model, Session as RattailSession
from rattail.threads import Thread
from rattail.csvutil import UnicodeDictWriter
from rattail.util import load_object, prettify
import formalchemy as fa
@ -64,7 +63,7 @@ class BatchMasterView(MasterView):
default_handler_spec = None
has_rows = True
rows_deletable = True
rows_downloadable = True
rows_downloadable_csv = True
refreshable = True
refresh_after_create = False
edit_with_rows = False
@ -905,47 +904,14 @@ class BatchMasterView(MasterView):
def get_execute_results_success_url(self, result, **kwargs):
return self.get_index_url()
def csv(self):
"""
Download batch data as CSV.
"""
batch = self.get_instance()
fields = self.get_csv_fields()
data = StringIO()
writer = UnicodeDictWriter(data, fields)
writer.writeheader()
for row in batch.data_rows:
if not row.removed:
writer.writerow(self.get_csv_row(row, 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=batch.csv'
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_row_class)
for prop in mapper.iterate_properties:
if isinstance(prop, orm.ColumnProperty):
if prop.key != 'removed' and not prop.key.endswith('uuid'):
fields.append(prop.key)
def get_row_csv_fields(self):
fields = super(BatchMasterView, self).get_row_csv_fields()
fields = [field for field in fields
if field != 'removed' and not field.endswith('uuid')]
return fields
def get_csv_row(self, row, fields):
"""
Return a dict for use when writing the row's data to CSV download.
"""
csvrow = {}
for field in fields:
value = getattr(row, field)
csvrow[field] = '' if value is None else unicode(value)
return csvrow
def get_row_results_csv_filename(self, batch):
return '{}.{}.csv'.format(self.get_route_prefix(), batch.id_str)
def clone(self):
"""
@ -1021,14 +987,6 @@ class BatchMasterView(MasterView):
config.add_tailbone_permission(permission_prefix, '{}.execute_multiple'.format(permission_prefix),
"Execute multiple {}".format(model_title_plural))
# download rows as CSV
if cls.rows_downloadable:
config.add_route('{}.csv'.format(route_prefix), '{}/{{uuid}}/csv'.format(url_prefix))
config.add_view(cls, attr='csv', route_name='{}.csv'.format(route_prefix),
permission='{}.csv'.format(permission_prefix))
config.add_tailbone_permission(permission_prefix, '{}.csv'.format(permission_prefix),
"Download {} rows as CSV".format(model_title))
class FileBatchMasterView(BatchMasterView):
"""