在 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,
),
]
我在自定义生成的表单文档中没有找到任何提示。
这是因为 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 对以创建链接。
如果您使用 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)),
...
]
然后,您可以使用管理仪表板中的复选框进行选择。