kopia lustrzana https://github.com/wagtail/wagtail
Alter forms spreadsheet export to use SpreadsheetExportMixin, enabling form submissions to be exported as xlsx as well
rodzic
8e88f3535c
commit
1d107abc7d
wagtail/contrib/forms
templates/wagtailforms
|
@ -102,7 +102,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button name="action" value="CSV" class="button bicolor icon icon-download">{% trans 'Download CSV' %}</button>
|
||||
<button name="action" value="export" class="button bicolor icon icon-download">{% trans 'Download spreadsheet' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import csv
|
||||
import datetime
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.core.paginator import InvalidPage
|
||||
from django.http import HttpResponse
|
||||
|
@ -10,6 +12,7 @@ from django.utils.translation import ungettext
|
|||
from django.views.generic import ListView, TemplateView
|
||||
|
||||
from wagtail.admin import messages
|
||||
from wagtail.admin.views.reports import SpreadsheetExportMixin
|
||||
from wagtail.contrib.forms.forms import SelectDateForm
|
||||
from wagtail.contrib.forms.utils import get_forms_for_user
|
||||
from wagtail.core.models import Page
|
||||
|
@ -131,7 +134,7 @@ class DeleteSubmissionsView(TemplateView):
|
|||
return context
|
||||
|
||||
|
||||
class SubmissionsListView(SafePaginateListView):
|
||||
class SubmissionsListView(SpreadsheetExportMixin, SafePaginateListView):
|
||||
""" Lists submissions for the provided form page """
|
||||
template_name = 'wagtailforms/index_submissions.html'
|
||||
context_object_name = 'submissions'
|
||||
|
@ -149,9 +152,13 @@ class SubmissionsListView(SafePaginateListView):
|
|||
if not get_forms_for_user(request.user).filter(pk=self.form_page.id).exists():
|
||||
raise PermissionDenied
|
||||
|
||||
self.is_csv_export = (self.request.GET.get('action') == 'CSV')
|
||||
if self.is_csv_export:
|
||||
self.is_export = (self.request.GET.get('action') == 'export')
|
||||
if self.is_export:
|
||||
self.paginate_by = None
|
||||
data_fields = self.form_page.get_data_fields()
|
||||
# Set the export fields and the headings for spreadsheet export
|
||||
self.list_export = [field for field, label in data_fields]
|
||||
self.export_heading_overrides = dict(data_fields)
|
||||
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
|
@ -174,7 +181,7 @@ class SubmissionsListView(SafePaginateListView):
|
|||
|
||||
def get_paginate_by(self, queryset):
|
||||
""" Get the number of items to paginate by, or ``None`` for no pagination """
|
||||
if self.is_csv_export:
|
||||
if self.is_export:
|
||||
return None
|
||||
return self.paginate_by
|
||||
|
||||
|
@ -182,7 +189,7 @@ class SubmissionsListView(SafePaginateListView):
|
|||
""" Return a dict of field names with ordering labels if ordering is valid """
|
||||
orderable_fields = self.orderable_fields or ()
|
||||
ordering = dict()
|
||||
if self.is_csv_export:
|
||||
if self.is_export:
|
||||
# Revert to CSV order_by submit_time ascending for backwards compatibility
|
||||
default_ordering = self.ordering_csv or ()
|
||||
else:
|
||||
|
@ -225,50 +232,30 @@ class SubmissionsListView(SafePaginateListView):
|
|||
result['submit_time__gte'] = date_from
|
||||
return result
|
||||
|
||||
def get_csv_filename(self):
|
||||
""" Returns the filename for the generated CSV file """
|
||||
return 'export-{}.csv'.format(
|
||||
def get_filename(self):
|
||||
""" Returns the base filename for the generated spreadsheet data file """
|
||||
return 'export-{}'.format(
|
||||
datetime.datetime.today().strftime('%Y-%m-%d')
|
||||
)
|
||||
|
||||
def get_csv_response(self, context):
|
||||
""" Returns a CSV response """
|
||||
filename = self.get_csv_filename()
|
||||
response = HttpResponse(content_type='text/csv; charset=utf-8')
|
||||
response['Content-Disposition'] = 'attachment;filename={}'.format(filename)
|
||||
|
||||
writer = csv.writer(response)
|
||||
writer.writerow(context['data_headings'])
|
||||
for data_row in context['data_rows']:
|
||||
writer.writerow(data_row)
|
||||
return response
|
||||
|
||||
def render_to_response(self, context, **response_kwargs):
|
||||
if self.is_csv_export:
|
||||
return self.get_csv_response(context)
|
||||
if self.is_export:
|
||||
return self.as_spreadsheet(context['submissions'])
|
||||
return super().render_to_response(context, **response_kwargs)
|
||||
|
||||
def to_row_dict(self, item):
|
||||
""" Orders the submission dictionary for spreadsheet writing """
|
||||
row_dict = OrderedDict((field, item.get_data().get(field)) for field in self.list_export)
|
||||
return row_dict
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
""" Return context for view, handle CSV or normal output """
|
||||
""" Return context for view """
|
||||
context = super().get_context_data(**kwargs)
|
||||
submissions = context[self.context_object_name]
|
||||
data_fields = self.form_page.get_data_fields()
|
||||
data_rows = []
|
||||
|
||||
if self.is_csv_export:
|
||||
# Build data_rows as list of lists containing formatted data values
|
||||
# Using smart_str prevents UnicodeEncodeError for values with non-ansi symbols
|
||||
for submission in submissions:
|
||||
form_data = submission.get_data()
|
||||
data_row = []
|
||||
for name, label in data_fields:
|
||||
val = form_data.get(name)
|
||||
if isinstance(val, list):
|
||||
val = ', '.join(val)
|
||||
data_row.append(smart_str(val))
|
||||
data_rows.append(data_row)
|
||||
data_headings = [smart_str(label) for name, label in data_fields]
|
||||
else:
|
||||
context['submissions'] = submissions
|
||||
if not self.is_export:
|
||||
# Build data_rows as list of dicts containing model_id and fields
|
||||
for submission in submissions:
|
||||
form_data = submission.get_data()
|
||||
|
@ -300,12 +287,11 @@ class SubmissionsListView(SafePaginateListView):
|
|||
'order': order_label,
|
||||
})
|
||||
|
||||
context.update({
|
||||
'form_page': self.form_page,
|
||||
'select_date_form': self.select_date_form,
|
||||
'data_headings': data_headings,
|
||||
'data_rows': data_rows,
|
||||
'submissions': submissions,
|
||||
})
|
||||
context.update({
|
||||
'form_page': self.form_page,
|
||||
'select_date_form': self.select_date_form,
|
||||
'data_headings': data_headings,
|
||||
'data_rows': data_rows,
|
||||
})
|
||||
|
||||
return context
|
||||
|
|
Ładowanie…
Reference in New Issue