Submission Hooks¶
Form submission hooks are used to process the cleaned_data of the form after a successful post. The only defined one is that to save the form submission data.
@register('process_form_submission')
def save_form_submission_data(instance, form):
""" saves the form submission data """
# copy the cleaned_data so we dont mess with the original
submission_data = form.cleaned_data.copy()
# change the submission data to a count of the files
for field in form.files.keys():
count = len(form.files.getlist(field))
submission_data[field] = '{} file{}'.format(count, pluralize(count))
# save the submission data
submission = instance.get_submission_class().objects.create(
form_data=json.dumps(submission_data, cls=FormSubmissionSerializer),
form=instance
)
# save the form files
for field in form.files:
for file in form.files.getlist(field):
FormSubmissionFile.objects.create(
submission=submission,
field=field,
file=file
)
You can disable this by setting WAGTAILSTREAMFORMS_ENABLE_BUILTIN_HOOKS=False
in your settings.py
Create your own hook¶
You can easily define additional hooks to perform a vast array of actions like
- send a mail
- save the data to a db
- reply to the sender
- etc
Here is a simple example to send an email with the submission data.
Create a wagtailstreamforms_hooks.py
in the root of one of your apps and add the following.
from django.conf import settings
from django.core.mail import EmailMessage
from django.template.defaultfilters import pluralize
from wagtailstreamforms.hooks import register
@register('process_form_submission')
def email_submission(instance, form):
""" Send an email with the submission. """
addresses = ['to@example.com']
content = ['Please see below submission\n', ]
from_address = settings.DEFAULT_FROM_EMAIL
subject = 'New Form Submission : %s' % instance.title
# build up the email content
for field, value in form.cleaned_data.items():
if field in form.files:
count = len(form.files.getlist(field))
value = '{} file{}'.format(count, pluralize(count))
elif isinstance(value, list):
value = ', '.join(value)
content.append('{}: {}'.format(field, value))
content = '\n'.join(content)
# create the email message
email = EmailMessage(
subject=subject,
body=content,
from_email=from_address,
to=addresses
)
# attach any files submitted
for field in form.files:
for file in form.files.getlist(field):
file.seek(0)
email.attach(file.name, file.read(), file.content_type)
# finally send the email
email.send(fail_silently=True)
A new option will appear in the setup of the forms to run the above hook. The name of the option is taken from
the function name so keep them unique to avoid confusion. The instance
is the form class instance, the
form
is the processed valid form in the request.