Form Customisation¶
Currently we have defined two different types of forms, one which just enables saving the submission and one to additionally email the results of the submission.
Custom basic form¶
You can easily add your own all you have to do is create a model that
inherits from wagtailstreamforms.models.BaseForm
add any additional fields or properties and
this will be added to the cms admin area.
Example:
from wagtailstreamforms.models import BaseForm
class CustomForm(BaseForm):
def process_form_submission(self, form):
super(CustomForm, self).process_form_submission(form) # handles the submission saving
# do your own stuff here
Custom email form¶
If you want to inherit the additional email sending functionality then inherit from
wagtailstreamforms.models.AbstractEmailForm
. The saving of the submission and sending of the email
is handled in the process_form_submission
so be sure to call super
if overriding that method.
Example:
from wagtailstreamforms.models import AbstractEmailForm
class CustomEmailForm(AbstractEmailForm):
""" As above with email sending. """
def process_form_submission(self, form):
super(CustomEmailForm, self).process_form_submission(form) # handles the submission saving and emailing
# do your own stuff here
Custom email form with content¶
Here is an example of an email form that has an additional RichTextField
rendered with the form.
This is especially useful if your form is being rendered from the template tag and you dont want to slot it in a streamfield.
Model:
from wagtail.wagtailadmin.edit_handlers import TabbedInterface, ObjectList, FieldPanel
from wagtail.wagtailcore.fields import RichTextField
from wagtailstreamforms.models import AbstractEmailForm, BaseForm
class EmailFormWithContent(AbstractEmailForm):
""" A form with content that sends and email. """
content = RichTextField(blank=True)
content_panels = [
FieldPanel('content', classname='full'),
]
edit_handler = TabbedInterface([
ObjectList(AbstractEmailForm.settings_panels, heading='General'),
ObjectList(AbstractEmailForm.field_panels, heading='Fields'),
ObjectList(AbstractEmailForm.email_panels, heading='Email Submission'),
ObjectList(content_panels, heading='Content'),
])
Template:
{% load wagtailcore_tags %}
<h2>{{ value.form.name }}</h2>
{% if value.form.content %}
<div class="form-content">{{ value.form.content|richtext }}</div>
{% endif %}
<form action="{{ value.form_action }}" method="post" novalidate>
{% csrf_token %}
{% for hidden in form.hidden_fields %}{{ hidden }}{% endfor %}
{% for field in form.visible_fields %}
{% include 'streamforms/partials/form_field.html' %}
{% endfor %}
<input type="submit" value="{{ value.form.submit_button_text }}">
</form>
Custom form submission model¶
If you need to save additional data, you can use a custom form submission model. To do this, you need to:
- Define a model that extends
wagtailstreamforms.models.AbstractFormSubmission
. - Override the
get_submission_class
andprocess_form_submission
methods in your form model.
Example:
import json
from django.core.serializers.json import DjangoJSONEncoder
from django.db import models
from django.utils.translation import ugettext_lazy as _
from wagtail.wagtailcore.models import Page
from wagtailstreamforms.models import AbstractFormSubmission, BaseForm
class CustomForm(BaseForm):
""" A form that saves the current user and page. """
def get_data_fields(self):
data_fields = super(ExampleForm, self).get_data_fields()
data_fields += [
('user', _('User')),
('page', _('Page'))
]
return data_fields
def get_submission_class(self):
return CustomFormSubmission
def process_form_submission(self, form):
if self.store_submission:
self.get_submission_class().objects.create(
form_data=json.dumps(form.cleaned_data, cls=DjangoJSONEncoder),
form=self,
page=form.page,
user=form.user if not form.user.is_anonymous() else None
)
class CustomFormSubmission(AbstractFormSubmission):
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
page = models.ForeignKey(Page)
def get_data(self):
form_data = super(CustomFormSubmission, self).get_data()
form_data.update({
'page': self.page,
'user': self.user
})
return form_data
Note
Its important to note here that the form.page
and form.user
seen above are passed in via the
before_serve_page
hook wagtailstreamforms.wagtail_hooks.process_form
.
If you want to use a different method of saving the form and you require these you will need to pass
them in yourself when adding request.POST
to the form.
Example usage can be seen in Providing your own submission method
Reference¶
-
class
wagtailstreamforms.models.
BaseForm
(*args, **kwargs)¶ A form base class, any form should inherit from this.
-
copy
()¶ Copy this form and its fields.
-
get_data_fields
()¶ Returns a list of tuples with (field_name, field_label).
-
get_form_fields
()¶ Form expects form_fields to be declared. If you want to change backwards relation name, you need to override this method.
-
get_submission_class
()¶ Returns submission class.
You can override this method to provide custom submission class. Your class must be inherited from AbstractFormSubmission.
-
process_form_submission
(form)¶ Accepts form instance with submitted data. Creates submission instance if self.store_submission = True.
You can override this method if you want to have custom creation logic. For example, you want to additionally send an email.
-
specific
¶ Return this form in its most specific subclassed form.
-
specific_class
¶ Return the class that this page would be if instantiated in its most specific form
-
-
class
wagtailstreamforms.models.
AbstractEmailForm
(*args, **kwargs)¶ A form that sends and email.
You can create custom form model based on this abstract model. For example, if you need a form that will send an email.
-
process_form_submission
(form)¶ Process the form submission and send an email.
-
send_form_mail
(form)¶ Send an email.
-
-
class
wagtailstreamforms.models.
AbstractFormSubmission
(*args, **kwargs)¶ Data for a form 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.
-
get_data
()¶ Returns dict with form data.
You can override this method to add additional data.
-