Add ability to download batch row data as CSV.
This commit is contained in:
parent
6c5eec7981
commit
73939b825e
|
@ -42,21 +42,25 @@
|
|||
</style>
|
||||
</%def>
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
<li>${h.link_to("Back to {0}".format(batch_display_plural), url(route_prefix))}</li>
|
||||
% if not batch.executed:
|
||||
% if form.updating:
|
||||
<li>${h.link_to("View this {0}".format(batch_display), url('{0}.view'.format(route_prefix), uuid=batch.uuid))}</li>
|
||||
% endif
|
||||
% if form.readonly and request.has_perm('{0}.edit'.format(permission_prefix)):
|
||||
<li>${h.link_to("Edit this {0}".format(batch_display), url('{0}.edit'.format(route_prefix), uuid=batch.uuid))}</li>
|
||||
% endif
|
||||
% endif
|
||||
% if request.has_perm('{0}.delete'.format(permission_prefix)):
|
||||
<li>${h.link_to("Delete this {0}".format(batch_display), url('{0}.delete'.format(route_prefix), uuid=batch.uuid))}</li>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<div class="form-wrapper">
|
||||
|
||||
<ul class="context-menu">
|
||||
<li>${h.link_to("Back to {0}".format(batch_display_plural), url(route_prefix))}</li>
|
||||
% if not batch.executed:
|
||||
% if form.updating:
|
||||
<li>${h.link_to("View this {0}".format(batch_display), url('{0}.view'.format(route_prefix), uuid=batch.uuid))}</li>
|
||||
% endif
|
||||
% if form.readonly and request.has_perm('{0}.edit'.format(permission_prefix)):
|
||||
<li>${h.link_to("Edit this {0}".format(batch_display), url('{0}.edit'.format(route_prefix), uuid=batch.uuid))}</li>
|
||||
% endif
|
||||
% endif
|
||||
% if request.has_perm('{0}.delete'.format(permission_prefix)):
|
||||
<li>${h.link_to("Delete this {0}".format(batch_display), url('{0}.delete'.format(route_prefix), uuid=batch.uuid))}</li>
|
||||
% endif
|
||||
${self.context_menu_items()}
|
||||
</ul>
|
||||
|
||||
${form.render(form_id='batch-form', buttons=capture(buttons))|n}
|
||||
|
|
|
@ -13,6 +13,13 @@
|
|||
</script>
|
||||
</%def>
|
||||
|
||||
<%def name="context_menu_items()">
|
||||
${parent.context_menu_items()}
|
||||
% if request.has_perm('{0}.csv'.format(permission_prefix)):
|
||||
<li>${h.link_to("Download this {0} as CSV".format(batch_display), url('{0}.csv'.format(route_prefix), uuid=batch.uuid))}</li>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="buttons()">
|
||||
<div class="buttons">
|
||||
% if not form.readonly and batch.refreshable:
|
||||
|
|
|
@ -32,6 +32,9 @@ from __future__ import unicode_literals
|
|||
import os
|
||||
import datetime
|
||||
import logging
|
||||
from cStringIO import StringIO
|
||||
|
||||
from sqlalchemy import orm
|
||||
|
||||
import formalchemy
|
||||
from pyramid.renderers import render_to_response
|
||||
|
@ -42,6 +45,7 @@ from webhelpers.html.tags import link_to, HTML
|
|||
from rattail.db import model
|
||||
from rattail.db import Session as RatSession
|
||||
from rattail.threads import Thread
|
||||
from rattail.csvutil import UnicodeDictWriter
|
||||
|
||||
from tailbone.db import Session
|
||||
from tailbone.views import SearchableAlchemyGridView, CrudView
|
||||
|
@ -366,6 +370,10 @@ class BatchCrud(BaseCrud):
|
|||
def batch_class(self):
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def batch_row_class(self):
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def mapped_class(self):
|
||||
return self.batch_class
|
||||
|
@ -705,6 +713,48 @@ class BatchCrud(BaseCrud):
|
|||
progress.session['success_url'] = self.view_url(batch.uuid)
|
||||
progress.session.save()
|
||||
|
||||
def csv(self):
|
||||
"""
|
||||
Download batch data as CSV.
|
||||
"""
|
||||
batch = self.current_batch()
|
||||
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.batch_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)
|
||||
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
|
||||
|
||||
|
||||
class FileBatchCrud(BatchCrud):
|
||||
"""
|
||||
|
@ -1163,6 +1213,11 @@ def defaults(config, batch_grid, batch_crud, row_grid, row_crud, url_prefix,
|
|||
config.add_view(batch_crud, attr='execute', route_name='{0}.execute'.format(route_prefix),
|
||||
permission='{0}.execute'.format(permission_prefix))
|
||||
|
||||
# Download batch row data as CSV
|
||||
config.add_route('{0}.csv'.format(route_prefix), '{0}{{uuid}}/csv'.format(url_prefix))
|
||||
config.add_view(batch_crud, attr='csv', route_name='{0}.csv'.format(route_prefix),
|
||||
permission='{0}.csv'.format(permission_prefix))
|
||||
|
||||
# Download batch data file
|
||||
if hasattr(batch_crud, 'download'):
|
||||
config.add_route('{0}.download'.format(route_prefix), '{0}{{uuid}}/download'.format(url_prefix))
|
||||
|
|
Loading…
Reference in a new issue