Search code examples
wagtailwagtail-adminwagtail-snippet

Is it possible to specify errors for individual InlinePanel items?


I know that errors can be added to the general admin form by using a custom form class (subclassing WagtailAdminModelForm) and using self.add_error("<field_name>", "<error_message>"). However is it also possible to add error message to the inline form items of an inline panel?

For example in my case it is forbidden to add duplicate entries in the inline panel. When the user adds duplicate items and tries to submit, all duplicate items should be highlighted with an error message.

Edit: I need to do this for a Snippet (not a Page)


Solution

  • You can set a unique together constraint on the Orderable class that checks the ParentalKey field against the field that needs to be unique. Wagtail display an error above the orderable list and an error on each of the subsequent duplicate fields (but not the first).

    For example, I have a TemplateTextSetItem Orderable class with a ParentalKey field set that points to a ClusterableModel class:

    class TemplateTextSetItem(Orderable):
        set = ParentalKey(
            "TemplateText",
            related_name="templatetext_items",
            help_text=_("Template Set to which this item belongs."),
            verbose_name="Set Name",
        )
        template_tag = models.CharField(
            max_length=50,
            help_text=_("Enter a tag without spaces, consisting of lowercase letters, numbers, and underscores.\nThe first character must be a lowercase letter."),
            verbose_name="Template Tag",
        )    
        text = models.TextField(
            null=True,
            blank=True,
            help_text=_("The text to be inserted in the template.")
        )
    
        panels = [
            FieldPanel('template_tag'),
            FieldPanel('text'),
        ]
    
        def __str__(self):
            return self.template_tag
    
        class Meta:
            unique_together = ('set', 'template_tag')
    

    If I enter a duplicate value for template_tag within the same parent TemplateText instance, I would get the following result:

    enter image description here

    (1, 2 & 3 all have the same template_tag value, 2 & 3 have field errors displayed on the form)

    If I was to enter 'test1' in a different parent instance, no error would be raised since it is unique in that instance.

    unique_together actually has a deprecation warning in Django and should be written as:

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=['set', 'template_tag'], 
                name='unique_set_template_tag'
                )
        ]
    

    Currently, Wagtail doesn't handle errors raised by UniqueConstraint and throws a 500 error instead. I think it might be coming in Wagtail 6.