Adds CSV output support

This commit is contained in:
Christopher Neugebauer 2016-10-14 11:11:27 -07:00
parent ea7a8d9ae7
commit 2637930996
2 changed files with 76 additions and 8 deletions

View file

@ -81,3 +81,16 @@ def model_fields_form_factory(model):
) )
return ModelFieldsForm return ModelFieldsForm
class SectionContentTypeForm(forms.Form):
section = forms.IntegerField(
required=False,
min_value=0,
widget=forms.HiddenInput(),
)
content_type = forms.CharField(
required=False,
widget=forms.HiddenInput(),
)

View file

@ -1,6 +1,10 @@
import csv
import forms
from django.contrib.auth.decorators import user_passes_test from django.contrib.auth.decorators import user_passes_test
from django.shortcuts import render from django.shortcuts import render
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import HttpResponse
from functools import wraps from functools import wraps
from registrasion import views from registrasion import views
@ -195,6 +199,10 @@ def report_view(title, form_type=None):
''' '''
# Consolidate form_type so it has format and section # Consolidate form_type so it has format and section
bases = [forms.SectionContentTypeForm, form_type]
bases = [base for base in bases if base is not None]
form_type = forms.mix_form(*bases)
# Create & return view # Create & return view
def _report(view): def _report(view):
@ -202,7 +210,7 @@ def report_view(title, form_type=None):
@wraps(view) @wraps(view)
@user_passes_test(views._staff_only) @user_passes_test(views._staff_only)
def inner_view(request, *a, **k): def inner_view(request, *a, **k):
return ReportView(request, view, title, form_type).render(*a, **k) return ReportView(request, view, title, form_type).view(*a, **k)
# Add this report to the list of reports. # Add this report to the list of reports.
_all_report_views.append(inner_view) _all_report_views.append(inner_view)
@ -213,37 +221,84 @@ def report_view(title, form_type=None):
class ReportView(object): class ReportView(object):
def __init__(self, request, view, title, form_type): def __init__(self, request, inner_view, title, form_type):
self.request = request self.request = request
self.view = view self.inner_view = inner_view
self.title = title self.title = title
self.form_type = form_type self.form_type = form_type
self._prepare()
def render(self, *a, **k): def view(self, *a, **k):
self._prepare_reports(*a, **k)
return self._render()
def _prepare(self):
# Create a form instance
if self.form_type is not None: if self.form_type is not None:
form = self.form_type(self.request.GET) form = self.form_type(self.request.GET)
# Pre-validate it
form.is_valid() form.is_valid()
else: else:
form = None form = None
reports = self.view(self.request, form, *a, **k) self.form = form
self.content_type = form.cleaned_data["content_type"]
self.section = form.cleaned_data["section"]
renderers = {
"text/csv": self._render_as_csv,
"text/html": self._render_as_html,
"": self._render_as_html,
}
self._render = renderers[self.content_type]
def _prepare_reports(self, *a, **k):
reports = self.inner_view(self.request, self.form, *a, **k)
if isinstance(reports, Report): if isinstance(reports, Report):
reports = [reports] reports = [reports]
self.reports = self._wrap_reports(reports)
def _render(self):
''' Replace with a specialist _render function '''
def _wrap_reports(self, reports):
reports = [ reports = [
_ReportTemplateWrapper("text/html", report) _ReportTemplateWrapper(self.content_type, report)
for report in reports for report in reports
] ]
return reports
def _render_as_html(self):
ctx = { ctx = {
"title": self.title, "title": self.title,
"form": form, "form": self.form,
"reports": reports, "reports": self.reports,
} }
return render(self.request, "registrasion/report.html", ctx) return render(self.request, "registrasion/report.html", ctx)
def _render_as_csv(self):
report = self.reports[self.section]
# Create the HttpResponse object with the appropriate CSV header.
response = HttpResponse(content_type='text/csv')
#response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
writer = csv.writer(response)
writer.writerow(list(report.headings()))
for row in report.rows():
writer.writerow(list(row))
return response
def get_all_reports(): def get_all_reports():
''' Returns all the views that have been registered with @report ''' ''' Returns all the views that have been registered with @report '''