3

In Wagtail document, I find an explanatory example showing how you can customize the behavior of admin form adding a few validation and save perks:

from django import forms
import geocoder  # not in Wagtail, for example only - http://geocoder.readthedocs.io/
from wagtail.admin.edit_handlers import FieldPanel
from wagtail.admin.forms import WagtailAdminPageForm
from wagtail.core.models import Page


class EventPageForm(WagtailAdminPageForm):
    address = forms.CharField()

    def clean(self):
        cleaned_data = super().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().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.arcgis(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(max_length=255)

    content_panels = [
        FieldPanel('title'),
        FieldPanel('start_date'),
        FieldPanel('end_date'),
        FieldPanel('address'),
    ]
    base_form_class = EventPageForm

All and all it shows how you can ensure date fields are set correct before saving the form and so on. Great, my question then will be if the form contains a parentalkey field ?? like this:

class EventPage(Page):
    start_date = models.DateField()
    end_date = models.DateField()
    duration = models.IntegerField()
    location = models.CharField(max_length=255)

    content_panels = [
        FieldPanel('title'),
        FieldPanel('start_date'),
        FieldPanel('end_date'),
        FieldPanel('address'),
        InlinePanel('image_relations')
    ]
    base_form_class = EventPageForm

class EventPageImageRelations(Orderable):
   parent = ParentalKey(
        EventPage,
        related_name="image_relations",
        on_delete=models.CASCADE
    )
    image = models.ForeignKey(
        'wagtailimages.Image',
        on_delete=models.CASCADE,
        related_name='+'
    )
   date = models.DateField()
    panels = [
        ImageChooserPanel('image'),
        FieldPanel('date')
    ]

Now, imagine that you'd like to run a check before saving to ensure that the designated date for each image is enter after the start_date. I find this challenging how can get the value on a form for a foreign key relation!

0 Answers0