Unable to use `CheckboxSelectMultiple` for choices in wagtails `FieldPanel`: Form field validation raises an error

321 Views Asked by At

In a wagtail settings model I have a CharField-based choice field and want that to behave as a multi select in Wagtails FieldPanel. The choices are rendered correctly as multiple checkboxes, but on submit the form validation will raise an error:

Select a valid choice. ['OPT1'] is not one of the available choices.

So how do I use text-based choices as a multi select in Wagtails FieldPanel?
Do I have to override the form field type to a forms.fields.MultipleChoiceField somehow?

Setting the widget attribute to Select - instead of CheckboxSelectMultiple - the correctly rendered and populated select dropdown widget works as expected.

My current implementation looks (roughly) like this:

# models.py

@register_setting(icon='cog')
class MySettings(BaseGenericSetting):

    class MyChoices(models.TextChoices):
        OPT_1 = "OPT1"
        OPT_2 = "OPT2"

    choicefield = models.CharField(
        max_length=4,
        blank=True,
        choices=MyChoices.choices,
    )

    panels = [
        FieldPanel(
            'choicefield',
            widget=forms.CheckboxSelectMultiple,
        ),
    ]

I did not find any hints in the Customising generated forms docs.

1

There are 1 best solutions below

4
Rich - enzedonline On

This'll be because CheckboxSelectMultiple is returning an array of selected items but the validator is expecting a single value found in MyChoices.

I think this is what you need:

class MyChoices(models.Model):
    item = models.CharField(max_length=255)

@register_setting(icon='cog')
class MySettings(BaseGenericSetting):
    choicefield = models.ManyToManyField(MyChoices)
    panels = [
        FieldPanel(
            'choicefield',
            widget=forms.CheckboxSelectMultiple,
        ),
    ]

You'd need to populate MyChoices from py command line or in the db admin, or register it as a snippet and add your values in the Wagtail admin interface.

Also, take a look at https://docs.wagtail.org/en/stable/getting_started/tutorial.html#tutorial-categories which creates a multi-multi choice field for blog categories using a ParentalManyToManyField. This is how I handle this scenario in Wagtail.

In the background, it sets up an intermediate table holding pairs of id's from each model to create the link.