无法使用 `CheckboxSelectMultiple` 进行 wagtails `FieldPanel` 中的选择:表单字段验证会引发错误

问题描述 投票:0回答:2

在 Wagtail 设置模型中,我有一个基于

CharField
的选择字段,并希望其在 Wagtails
FieldPanel
中充当多重选择。这些选项正确呈现为多个复选框,但在提交时,表单验证将引发错误:

选择一个有效的选项。 ['OPT1'] 不是可用的选择之一。

那么如何在 Wagtails 中使用基于文本的选择作为多重选择

FieldPanel

我是否必须以某种方式将表单字段类型覆盖为
forms.fields.MultipleChoiceField

widget
属性设置为
Select
- 而不是
CheckboxSelectMultiple
- 正确渲染和填充的选择下拉小部件按预期工作。

我当前的实现看起来(大致)是这样的:

# 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,
        ),
    ]

我在自定义生成的表单文档中没有找到任何提示。

django wagtail multiplechoicefield
2个回答
0
投票

这是因为 CheckboxSelectMultiple 返回所选项目的数组,但验证器期望在 MyChoices 中找到单个值。

认为这就是你所需要的:

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,
        ),
    ]

您需要从 py 命令行或数据库管理中填充 MyChoices,或者将其注册为片段并在 Wagtail 管理界面中添加您的值。

另外,请查看 https://docs.wagtail.org/en/stable/getting_started/tutorial.html#tutorial-categories,它使用 ParentalManyToManyField 为博客类别创建多选字段。这就是我在 Wagtail 中处理这种情况的方式。

在后台,它设置一个中间表,其中包含每个模型的 ID 对以创建链接。


0
投票

如果您使用 Postgres 作为数据库,那么您可以使用 ArrayField 来完成此操作。

使用您的示例,代码将如下所示:

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


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

class CheckboxSelectMultipleList(forms.CheckboxSelectMultiple):
    def format_value(self, value):
        if isinstance(value, str):
            return value.split(',')

panels = [
    ...
    
    FieldPanel('choicefield', widget=CheckboxSelectMultipleList(choices=MyChoices.choices)),
    
    ...
]

然后,您可以使用管理仪表板中的复选框进行选择。

© www.soinside.com 2019 - 2024. All rights reserved.