From b727ec40641fd1059d936976fec7622fab7d0e1a Mon Sep 17 00:00:00 2001 From: Tim Heap Date: Tue, 3 May 2016 17:28:33 +1000 Subject: [PATCH] Add documentation on the base_form_class attribute --- .../customisation/page_editing_interface.rst | 72 +++++++++++++++++++ docs/reference/pages/model_reference.rst | 7 ++ 2 files changed, 79 insertions(+) diff --git a/docs/advanced_topics/customisation/page_editing_interface.rst b/docs/advanced_topics/customisation/page_editing_interface.rst index 8a5fc68d47..817554f2a4 100644 --- a/docs/advanced_topics/customisation/page_editing_interface.rst +++ b/docs/advanced_topics/customisation/page_editing_interface.rst @@ -112,3 +112,75 @@ To begin, import the ``Format`` class, ``register_image_format`` function, and o To unregister, call ``unregister_image_format`` with the string of the ``name`` of the ``Format`` as the only argument. + +.. _custom_edit_handler_forms: + +Customising generated forms +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. class:: wagtail.wagtailadmin.forms.WagtailAdminModelForm +.. class:: wagtail.wagtailadmin.forms.WagtailAdminPageForm + +Wagtail automatically generates forms using the panels configured on the model. +By default, this form subclasses :class:`~wagtail.wagtailadmin.forms.WagtailAdminModelForm`, +or :class:`~wagtail.wagtailadmin.forms.WagtailAdminPageForm` for pages. +A custom base form class can be configured by setting the :attr:`base_form_class` attribute on any model. +Custom forms for snippets must subclass :class:`~wagtail.wagtailadmin.forms.WagtailAdminModelForm`, +and custom forms for pages must subclass :class:`~wagtail.wagtailadmin.forms.WagtailAdminPageForm`. + +This can be used to add non-model fields to the form, to automatically generate field content, +or to add custom validation logic for your models: + +.. code-block:: python + + from django import forms + from wagtail.wagtailadmin.edit_handlers import FieldPanel + from wagtail.wagtailadmin.forms import WagtailAdminPageForm + from wagtail.wagtailcore.models import Page + + + class EventPageForm(WagtailAdminPageForm): + address = forms.CharField() + + def clean(self): + cleaned_data = super(EventPageForm, self).clean() + + # Make sure that the event starts before it ends + start_date = cleaned_data['start_date'] + end_date = cleaned_data['end_date'] + if start_date and end_date and start_date > end_date: + self.add_error('end_date', 'The end date must be after the start date') + + return cleaned_data + + def save(self, commit=True): + page = super(EventPageForm, self).save(commit=False) + + # Update the duration field from the submitted dates + page.duration = (page.end_date - page.start_date).days + + # Fetch the location by geocoding the address + page.location = geocoder.get_coordinates(self.cleaned_data['address']) + + if commit: + page.save() + return page + + + class EventPage(Page): + start_date = models.DateField() + end_date = models.DateField() + duration = models.IntegerField() + location = models.CharField() + + content_panels = [ + FieldPanel('given_name'), + FieldPanel('family_name'), + FieldPanel('bio'), + ] + base_form_class = EventPageForm + +Wagtail will generate a new subclass of this form for the model, +adding any fields defined in ``panels`` or ``content_panels``. +Any fields already defined on the model will not be overridden by these automatically added fields, +so the form field for a model field can be overridden by adding it to the custom form. diff --git a/docs/reference/pages/model_reference.rst b/docs/reference/pages/model_reference.rst index c8d8ad938e..e71dbbab97 100644 --- a/docs/reference/pages/model_reference.rst +++ b/docs/reference/pages/model_reference.rst @@ -171,6 +171,13 @@ In addition to the model fields provided, ``Page`` has many properties and metho Controls if this page can be created through the Wagtail administration. Defaults to True, and is not inherited by subclasses. This is useful when using `multi-table inheritance `_, to stop the base model from being created as an actual page. + .. attribute:: base_form_class + + The form class used as a base for editing Pages of this type in the Wagtail page editor. + This attribute can be set on a model to customise the Page editor form. + Forms must be a subclass of :class:`~wagtail.wagtailadmin.forms.WagtailAdminPageForm`. + See :ref:`custom_edit_handler_forms` for more information. + ``Site`` ========