commit
						c76c0f6f4b
					
				
					 3 changed files with 120 additions and 32 deletions
				
			
		|  | @ -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 | ||||||
|  | @ -194,44 +198,114 @@ def report_view(title, form_type=None): | ||||||
| 
 | 
 | ||||||
|     ''' |     ''' | ||||||
| 
 | 
 | ||||||
|  |     # Create & return view | ||||||
|     def _report(view): |     def _report(view): | ||||||
| 
 |         report_view = ReportView(view, title, form_type) | ||||||
|         @wraps(view) |         report_view = user_passes_test(views._staff_only)(report_view) | ||||||
|         @user_passes_test(views._staff_only) |         report_view = wraps(view)(report_view) | ||||||
|         def inner_view(request, *a, **k): |  | ||||||
| 
 |  | ||||||
|             if form_type is not None: |  | ||||||
|                 form = form_type(request.GET) |  | ||||||
|                 form.is_valid() |  | ||||||
|             else: |  | ||||||
|                 form = None |  | ||||||
| 
 |  | ||||||
|             reports = view(request, form, *a, **k) |  | ||||||
| 
 |  | ||||||
|             if isinstance(reports, Report): |  | ||||||
|                 reports = [reports] |  | ||||||
| 
 |  | ||||||
|             reports = [ |  | ||||||
|                 _ReportTemplateWrapper("text/html", report) |  | ||||||
|                 for report in reports |  | ||||||
|             ] |  | ||||||
| 
 |  | ||||||
|             ctx = { |  | ||||||
|                 "title": title, |  | ||||||
|                 "form": form, |  | ||||||
|                 "reports": reports, |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return render(request, "registrasion/report.html", ctx) |  | ||||||
| 
 | 
 | ||||||
|         # 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(report_view) | ||||||
|  | 
 | ||||||
|  |         return report_view | ||||||
| 
 | 
 | ||||||
|         # Return the callable |  | ||||||
|         return inner_view |  | ||||||
|     return _report |     return _report | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class ReportView(object): | ||||||
|  | 
 | ||||||
|  |     def __init__(self, inner_view, title, form_type): | ||||||
|  |         # Consolidate form_type so it has content type and section | ||||||
|  |         self.inner_view = inner_view | ||||||
|  |         self.title = title | ||||||
|  |         self.form_type = form_type | ||||||
|  | 
 | ||||||
|  |     def __call__(self, request, *a, **k): | ||||||
|  |         data = ReportViewRequestData(self, request, *a, **k) | ||||||
|  |         return self.render(data) | ||||||
|  | 
 | ||||||
|  |     def get_form(self, request): | ||||||
|  | 
 | ||||||
|  |         # Create a form instance | ||||||
|  |         if self.form_type is not None: | ||||||
|  |             form = self.form_type(request.GET) | ||||||
|  | 
 | ||||||
|  |             # Pre-validate it | ||||||
|  |             form.is_valid() | ||||||
|  |         else: | ||||||
|  |             form = None | ||||||
|  | 
 | ||||||
|  |         return form | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def wrap_reports(cls, reports, content_type): | ||||||
|  |         reports = [ | ||||||
|  |             _ReportTemplateWrapper(content_type, report) | ||||||
|  |             for report in reports | ||||||
|  |         ] | ||||||
|  | 
 | ||||||
|  |         return reports | ||||||
|  | 
 | ||||||
|  |     def render(self, data): | ||||||
|  |         renderers = { | ||||||
|  |             "text/csv": self._render_as_csv, | ||||||
|  |             "text/html": self._render_as_html, | ||||||
|  |             None: self._render_as_html, | ||||||
|  |         } | ||||||
|  |         render = renderers[data.content_type] | ||||||
|  |         return render(data) | ||||||
|  | 
 | ||||||
|  |     def _render_as_html(self, data): | ||||||
|  |         ctx = { | ||||||
|  |             "title": self.title, | ||||||
|  |             "form": data.form, | ||||||
|  |             "reports": data.reports, | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return render(data.request, "registrasion/report.html", ctx) | ||||||
|  | 
 | ||||||
|  |     def _render_as_csv(self, data): | ||||||
|  |         report = data.reports[data.section] | ||||||
|  | 
 | ||||||
|  |         # Create the HttpResponse object with the appropriate CSV header. | ||||||
|  |         response = HttpResponse(content_type='text/csv') | ||||||
|  | 
 | ||||||
|  |         writer = csv.writer(response) | ||||||
|  |         encode = lambda i: i.encode("utf8") if isinstance(i, unicode) else i | ||||||
|  |         writer.writerow(list(encode(i) for i in report.headings())) | ||||||
|  |         for row in report.rows(): | ||||||
|  |             writer.writerow(list(encode(i) for i in row)) | ||||||
|  | 
 | ||||||
|  |         return response | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ReportViewRequestData(object): | ||||||
|  | 
 | ||||||
|  |     def __init__(self, report_view, request, *a, **k): | ||||||
|  |         self.report_view = report_view | ||||||
|  |         self.request = request | ||||||
|  | 
 | ||||||
|  |         # Calculate other data | ||||||
|  |         self.form = report_view.get_form(request) | ||||||
|  | 
 | ||||||
|  |         # Content type and section come from request.GET | ||||||
|  |         self.content_type = request.GET.get("content_type") | ||||||
|  |         self.section = request.GET.get("section") | ||||||
|  |         self.section = int(self.section) if self.section else None | ||||||
|  | 
 | ||||||
|  |         # Reports come from calling the inner view | ||||||
|  |         reports = report_view.inner_view(request, self.form, *a, **k) | ||||||
|  | 
 | ||||||
|  |         # Normalise to a list | ||||||
|  |         if isinstance(reports, Report): | ||||||
|  |             reports = [reports] | ||||||
|  | 
 | ||||||
|  |         # Wrap them in appropriate format | ||||||
|  |         reports = ReportView.wrap_reports(reports, self.content_type) | ||||||
|  | 
 | ||||||
|  |         self.reports = reports | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 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 ''' | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -408,7 +408,7 @@ def attendee(request, form, user_id=None): | ||||||
|     ''' Returns a list of all manifested attendees if no attendee is specified, |     ''' Returns a list of all manifested attendees if no attendee is specified, | ||||||
|     else displays the attendee manifest. ''' |     else displays the attendee manifest. ''' | ||||||
| 
 | 
 | ||||||
|     if user_id is None and not form.has_changed(): |     if user_id is None: | ||||||
|         return attendee_list(request) |         return attendee_list(request) | ||||||
| 
 | 
 | ||||||
|     if form.cleaned_data["user"] is not None: |     if form.cleaned_data["user"] is not None: | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ from registrasion.controllers.item import ItemController | ||||||
| 
 | 
 | ||||||
| from django import template | from django import template | ||||||
| from django.db.models import Sum | from django.db.models import Sum | ||||||
|  | from urllib import urlencode | ||||||
| 
 | 
 | ||||||
| register = template.Library() | register = template.Library() | ||||||
| 
 | 
 | ||||||
|  | @ -74,3 +75,16 @@ def items_purchased(context, category=None): | ||||||
|     return ItemController(context.request.user).items_purchased( |     return ItemController(context.request.user).items_purchased( | ||||||
|         category=category |         category=category | ||||||
|     ) |     ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @register.assignment_tag(takes_context=True) | ||||||
|  | def report_as_csv(context, section): | ||||||
|  | 
 | ||||||
|  |     old_query = context.request.META["QUERY_STRING"] | ||||||
|  |     query = dict([("section", section), ("content_type", "text/csv")]) | ||||||
|  |     querystring = urlencode(query) | ||||||
|  | 
 | ||||||
|  |     if old_query: | ||||||
|  |         querystring = old_query + "&" + querystring | ||||||
|  | 
 | ||||||
|  |     return context.request.path + "?" + querystring | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Christopher Neugebauer
						Christopher Neugebauer