Add export to CSV support for form submissions and

convert form submissions to have a generic relation with the specific Form
for which they were created instead of a Page.
This commit is contained in:
Serafeim Papastefanos 2014-03-23 19:26:00 +02:00
parent 521b1c47a1
commit 9d65be0d66
3 changed files with 43 additions and 10 deletions

View file

@ -1,5 +1,6 @@
from django.conf import settings
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.shortcuts import render
@ -38,7 +39,10 @@ class FormSubmission(models.Model):
"""Data for a Form submission."""
form_data = models.TextField()
form_page = models.ForeignKey('wagtailcore.Page',related_name='+')
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
form_page = generic.GenericForeignKey('content_type', 'object_id')
submit_time = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
@ -126,11 +130,13 @@ class AbstractForm(Page):
i for i in self.form.data.items()
if i[0] != 'csrfmiddlewaretoken'
)
FormSubmission.objects.create(
submission = FormSubmission.objects.create(
form_data = json.dumps(form_data),
form_page = self,
user = request.user,
)
# If we have a form_processing_backend call its process method
if hasattr(self, 'form_processing_backend'):
form_processor = self.form_processing_backend()

View file

@ -37,16 +37,18 @@
{% blocktrans with form_title=form_page.title|capfirst %}Submissions of <span>{{ form_title }}</span>{% endblocktrans %}
</h1>
</div>
<form class="col" action="" method="get">
<form class="col6" action="" method="get">
<ul class="fields">
{% for field in select_date_form %}
<div class="right col3">
<div class="col3">
{% include "wagtailadmin/shared/field_as_li.html" with field=field %}
</div>
{% endfor %}
<div class='col3'
<li class="submit"><input type="submit" value="Filter" /></li>
<div class='col2'
<li class="submit"><input name='action' type="submit" value="Filter" />
<br /><input name='action' type="submit" value="CSV" /></li>
</div>
</ul>
</form>

View file

@ -1,7 +1,9 @@
import datetime
import json
import unicodecsv
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.http import Http404
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, render, redirect
from django.utils.text import capfirst
from django.contrib.contenttypes.models import ContentType
@ -43,21 +45,44 @@ def list_submissions(request, app_label, model, id):
model = get_form_type_from_url_params(app_label, model).model_class()
form_page = get_object_or_404(model, id=id)
submissions = FormSubmission.objects.filter(form_page=form_page)
#submissions = FormSubmission.objects.filter(form_page=form_page)
submissions = FormSubmission.objects.filter(content_type = form_page.content_type, object_id=form_page.id)
select_date_form = SelectDateForm(request.GET)
if select_date_form.is_valid():
date_from = select_date_form.cleaned_data.get('date_from')
date_to = select_date_form.cleaned_data.get('date_to')
# careful: date_to should be increased by 1 day since the submit_time
# is a time so it will always be greater
date_to += datetime.timedelta(days=1)
if date_to:
date_to += datetime.timedelta(days=1)
if date_from and date_to:
submissions=submissions.filter(submit_time__range=[date_from, date_to] )
elif date_from and not date_to:
submissions=submissions.filter(submit_time__gte=date_from)
elif not date_from and date_to:
submissions=submissions.filter(submit_time__lte=date_to)
if request.GET.get('action')=='CSV':
# return a CSV instead
response = HttpResponse(content_type='text/csv; charset=utf-8')
response['Content-Disposition'] = 'attachment;filename=export.csv'
writer = unicodecsv.writer(response, encoding='utf-8')
if submissions:
extra_keys = json.loads(submissions[0].form_data).keys()
header_row = ['Submission date', 'user',]
header_row.extend(extra_keys)
writer.writerow(header_row)
for s in submissions:
data_row = [s.submit_time, s.user]
form_data = json.loads(s.form_data)
for ek in extra_keys:
data_row.append( form_data.get(ek) )
writer.writerow(data_row)
return response
p = request.GET.get('p', 1)
paginator = Paginator(submissions, 20)