2
0

index.rst 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. .. _form_builder:
  2. Form builder
  3. ============
  4. The ``wagtailforms`` module allows you to set up single-page forms, such as a 'Contact us' form, as pages of a Wagtail site. It provides a set of base models that site implementers can extend to create their own ``FormPage`` type with their own site-specific templates. Once a page type has been set up in this way, editors can build forms within the usual page editor, consisting of any number of fields. Form submissions are stored for later retrieval through a new 'Forms' section within the Wagtail admin interface; in addition, they can be optionally e-mailed to an address specified by the editor.
  5. .. note::
  6. **wagtailforms is not a replacement for** :doc:`Django's form support <django:topics/forms/index>`. It is designed as a way for page authors to build general-purpose data collection forms without having to write code. If you intend to build a form that assigns specific behaviour to individual fields (such as creating user accounts), or needs a custom HTML layout, you will almost certainly be better served by a standard Django form, where the fields are fixed in code rather than defined on-the-fly by a page author. See the `wagtail-form-example project <https://github.com/gasman/wagtail-form-example/commits/master>`_ for an example of integrating a Django form into a Wagtail page.
  7. .. _form_builder_usage:
  8. Usage
  9. ~~~~~
  10. Add ``wagtail.contrib.forms`` to your ``INSTALLED_APPS``:
  11. .. code-block:: python
  12. INSTALLED_APPS = [
  13. ...
  14. 'wagtail.contrib.forms',
  15. ]
  16. Within the ``models.py`` of one of your apps, create a model that extends ``wagtail.contrib.forms.models.AbstractEmailForm``:
  17. .. code-block:: python
  18. from django.db import models
  19. from modelcluster.fields import ParentalKey
  20. from wagtail.admin.edit_handlers import (
  21. FieldPanel, FieldRowPanel,
  22. InlinePanel, MultiFieldPanel
  23. )
  24. from wagtail.core.fields import RichTextField
  25. from wagtail.contrib.forms.models import AbstractEmailForm, AbstractFormField
  26. class FormField(AbstractFormField):
  27. page = ParentalKey('FormPage', on_delete=models.CASCADE, related_name='form_fields')
  28. class FormPage(AbstractEmailForm):
  29. intro = RichTextField(blank=True)
  30. thank_you_text = RichTextField(blank=True)
  31. content_panels = AbstractEmailForm.content_panels + [
  32. FieldPanel('intro', classname="full"),
  33. InlinePanel('form_fields', label="Form fields"),
  34. FieldPanel('thank_you_text', classname="full"),
  35. MultiFieldPanel([
  36. FieldRowPanel([
  37. FieldPanel('from_address', classname="col6"),
  38. FieldPanel('to_address', classname="col6"),
  39. ]),
  40. FieldPanel('subject'),
  41. ], "Email"),
  42. ]
  43. ``AbstractEmailForm`` defines the fields ``to_address``, ``from_address`` and ``subject``, and expects ``form_fields`` to be defined. Any additional fields are treated as ordinary page content - note that ``FormPage`` is responsible for serving both the form page itself and the landing page after submission, so the model definition should include all necessary content fields for both of those views.
  44. Date and datetime values in a form response will be formatted with the `SHORT_DATE_FORMAT <https://docs.djangoproject.com/en/3.0/ref/settings/#short-date-format>`_ and `SHORT_DATETIME_FORMAT <https://docs.djangoproject.com/en/3.0/ref/settings/#short-datetime-format>`_ respectively. (see :ref:`form_builder_render_email` for how to customise the email content).
  45. If you do not want your form page type to offer form-to-email functionality, you can inherit from AbstractForm instead of ``AbstractEmailForm``, and omit the ``to_address``, ``from_address`` and ``subject`` fields from the ``content_panels`` definition.
  46. You now need to create two templates named ``form_page.html`` and ``form_page_landing.html`` (where ``form_page`` is the underscore-formatted version of the class name). ``form_page.html`` differs from a standard Wagtail template in that it is passed a variable ``form``, containing a Django ``Form`` object, in addition to the usual ``page`` variable. A very basic template for the form would thus be:
  47. .. code-block:: html+django
  48. {% load wagtailcore_tags %}
  49. <html>
  50. <head>
  51. <title>{{ page.title }}</title>
  52. </head>
  53. <body>
  54. <h1>{{ page.title }}</h1>
  55. {{ page.intro|richtext }}
  56. <form action="{% pageurl page %}" method="POST">
  57. {% csrf_token %}
  58. {{ form.as_p }}
  59. <input type="submit">
  60. </form>
  61. </body>
  62. </html>
  63. ``form_page_landing.html`` is a standard Wagtail template, displayed after the user makes a successful form submission, `form_submission` will available in this template. If you want to dynamically override the landing page template, you can do so with the ``get_landing_page_template`` method (in the same way that you would with ``get_template``).
  64. .. _wagtailforms_formsubmissionpanel:
  65. Displaying form submission information
  66. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  67. ``FormSubmissionsPanel`` can be added to your page's panel definitions to display the number of form submissions and the time of the most recent submission, along with a quick link to access the full submission data:
  68. .. code-block:: python
  69. from wagtail.contrib.forms.edit_handlers import FormSubmissionsPanel
  70. class FormPage(AbstractEmailForm):
  71. # ...
  72. content_panels = AbstractEmailForm.content_panels + [
  73. FormSubmissionsPanel(),
  74. FieldPanel('intro', classname="full"),
  75. # ...
  76. ]
  77. Index
  78. ~~~~~
  79. .. toctree::
  80. :maxdepth: 1
  81. customisation