Ability to change FormSubmission class

pull/2969/head
Mikalai Radchuk 2016-05-13 17:19:45 +03:00 zatwierdzone przez Matt Westcott
rodzic eca66c409d
commit 0451d65bc9
4 zmienionych plików z 84 dodań i 25 usunięć

Wyświetl plik

@ -35,8 +35,13 @@ FORM_FIELD_CHOICES = (
@python_2_unicode_compatible
class FormSubmission(models.Model):
"""Data for a Form submission."""
class AbstractFormSubmission(models.Model):
"""
Data for a survey submission.
You can create custom submission model based on this abstract model.
For example, if you need to save additional data or a reference to a user.
"""
form_data = models.TextField()
page = models.ForeignKey(Page, on_delete=models.CASCADE)
@ -44,15 +49,30 @@ class FormSubmission(models.Model):
submit_time = models.DateTimeField(verbose_name=_('submit time'), auto_now_add=True)
def get_data(self):
return json.loads(self.form_data)
"""
Returns dict with form data.
You can override this method to add additional data.
"""
form_data = json.loads(self.form_data)
form_data.update({
'submit_time': self.submit_time,
})
return form_data
def __str__(self):
return self.form_data
class Meta:
abstract = True
verbose_name = _('form submission')
class FormSubmission(AbstractFormSubmission):
"""Data for a Form submission."""
class AbstractFormField(Orderable):
"""
Database Fields required for building a Django Form field.
@ -142,8 +162,32 @@ class AbstractForm(Page):
class Meta:
abstract = True
def get_form_fields(self):
"""
Form page expects `form_fields` to be declared.
If you want to change backwards relation name,
you need to override this method.
"""
return self.form_fields.all()
def get_data_fields(self):
"""
Returns a list of tuples with (field_name, field_label).
"""
data_fields = [
('submit_time', _('Submission date')),
]
data_fields += [
(field.clean_name, field.label)
for field in self.get_form_fields()
]
return data_fields
def get_form_class(self):
fb = self.form_builder(self.form_fields.all())
fb = self.form_builder(self.get_form_fields())
return fb.get_form_class()
def get_form_parameters(self):
@ -156,13 +200,31 @@ class AbstractForm(Page):
return form_class(*args, **form_params)
def get_submission_class(self):
"""
Returns submission class.
You can override this method to provide custom submission class.
Your class must be inherited from AbstractFormSubmission.
"""
return FormSubmission
def process_form_submission(self, form):
return FormSubmission.objects.create(
"""
Accepts form instance with submitted data, user and page.
Creates submission instance.
You can override this method if you want to have custom creation logic.
For example, if you want to save reference to a user.
"""
self.get_submission_class().objects.create(
form_data=json.dumps(form.cleaned_data, cls=DjangoJSONEncoder),
page=self,
)
def serve(self, request):
def serve(self, request, *args, **kwargs):
if request.method == 'POST':
form = self.get_form(request.POST)

Wyświetl plik

@ -6,7 +6,6 @@
<col />
<thead>
<tr>
<th>{% trans "Submission Date" %}</th>
{% for heading in data_headings %}
<th>{{ heading }}</th>
{% endfor %}

Wyświetl plik

@ -325,7 +325,7 @@ class TestFormBuilder(TestCase):
)
# Create a form builder
self.fb = FormBuilder(self.form_page.form_fields.all())
self.fb = FormBuilder(self.form_page.get_form_fields())
def test_fields(self):
"""

Wyświetl plik

@ -13,7 +13,7 @@ from wagtail.utils.pagination import paginate
from wagtail.wagtailadmin import messages
from wagtail.wagtailcore.models import Page
from wagtail.wagtailforms.forms import SelectDateForm
from wagtail.wagtailforms.models import FormSubmission, get_forms_for_user
from wagtail.wagtailforms.models import get_forms_for_user
def index(request):
@ -30,8 +30,8 @@ def delete_submission(request, page_id, submission_id):
if not get_forms_for_user(request.user).filter(id=page_id).exists():
raise PermissionDenied
submission = get_object_or_404(FormSubmission, id=submission_id)
page = get_object_or_404(Page, id=page_id)
page = get_object_or_404(Page, id=page_id).specific
submission = get_object_or_404(page.get_submission_class(), id=submission_id)
if request.method == 'POST':
submission.delete()
@ -46,17 +46,16 @@ def delete_submission(request, page_id, submission_id):
def list_submissions(request, page_id):
form_page = get_object_or_404(Page, id=page_id).specific
if not get_forms_for_user(request.user).filter(id=page_id).exists():
raise PermissionDenied
data_fields = [
(field.clean_name, field.label)
for field in form_page.form_fields.all()
]
form_page = get_object_or_404(Page, id=page_id).specific
form_submission_class = form_page.get_submission_class()
submissions = FormSubmission.objects.filter(page=form_page)
data_fields = form_page.get_data_fields()
submissions = form_submission_class.objects.filter(page=form_page)
data_headings = [label for name, label in data_fields]
select_date_form = SelectDateForm(request.GET)
if select_date_form.is_valid():
@ -78,13 +77,13 @@ def list_submissions(request, page_id):
response = HttpResponse(content_type='text/csv; charset=utf-8')
response['Content-Disposition'] = 'attachment;filename=export.csv'
# Prevents UnicodeEncodeError for questions with non-ansi symbols
data_headings = [smart_str(label) for label in data_headings]
writer = csv.writer(response)
header_row = ['Submission date'] + [smart_str(label) for name, label in data_fields]
writer.writerow(header_row)
writer.writerow(data_headings)
for s in submissions:
data_row = [s.submit_time]
data_row = []
form_data = s.get_data()
for name, label in data_fields:
data_row.append(smart_str(form_data.get(name)))
@ -93,11 +92,10 @@ def list_submissions(request, page_id):
paginator, submissions = paginate(request, submissions)
data_headings = [label for name, label in data_fields]
data_rows = []
for s in submissions:
form_data = s.get_data()
data_row = [s.submit_time] + [form_data.get(name) for name, label in data_fields]
data_row = [form_data.get(name) for name, label in data_fields]
data_rows.append({
"model_id": s.id,
"fields": data_row