CommaSeparatedIntegerField 的表单小部件

Form Widget for CommaSeparatedIntegerField

我有一个问题,有人可以 select 从给定的集合中选择多个选项。像这样:

A 是什么?

  1. B
  2. C
  3. D

在这里,填写表格的人可以select 3 个选项的任意组合。例如,B、C、BC、BCD

我正在尝试将此信息存储在数据库中。

我的模型中的一个字段是 CommaSeparatedIntegerField,如下所示:

class Tutor(models.Model):
    want_list = models.CommaSeparatedIntegerField(max_length=50, null=True,)

我创建了一个使用此模型的表单,如下所示:

class MyForm(forms.ModelForm):      
    class Meta:
        model = Tutor
        fields = ['want_list']
        widgets = {'want_list': forms.CheckboxSelectMultiple(choices=P3_CHOICES),}

由于我获得的默认小部件是 TextInput,因此我将小部件更改为 CheckboxSelectMultiple。我正在使用软盘格式。

但是,这种方式似乎无法验证数据。这是我得到的错误:

“仅输入以逗号分隔的数字。”

...每当我 select 任何选项并尝试提交表格时。

如何修复此错误?我在模型中使用了错误的字段吗?或者表单中的错误小部件?实现这样的目标的一般方法是什么?我想这是许多网站上常见的事情,一定有一些我不知道的标准方法来解决这个问题。

提前致谢。

编辑:

P3_CHOICES = (
    (1, 'B'),
    (2, 'C'),
    (3, 'D'),        
)

这是因为 CheckboxSelectMultiple 的值将被 Django 反序列化为一个值列表(例如:['1', '2']),而不是逗号分隔的整数列表(例如:'1,2') CommaSeparatedIntegerField 期望。

一个解决方案是创建 CheckboxSelectMultiple 的子类来满足您的需求:

class CommaSeparatedCheckboxSelectMultiple(CheckboxSelectMultiple):
    def value_from_datadict(self, *args, **kwargs):
        data_list = super(CommaSeparatedCheckboxSelectMultiple, self).value_from_datadict(*args, **kwargs)
        return ','.join(data_list)

虽然aumo的出色回答完美解决了我的问题,但我意识到我在某种程度上是在尝试重新发明轮子。因此,我开始搜索并找到了一个很棒的 Python 软件包,它完全可以满足我的要求。

https://pypi.python.org/pypi/django-multiselectfield/

这是我的实现:

models.py

from multiselectfield import MultiSelectField

P3_CHOICES = (
    (1, 'B'),
    (2, 'C'),
    (3, 'D'),        
)

class Tutor(models.Model):
    want_list = MultiSelectField(choices=P3_CHOICES, null=True)

forms.py

class MyForm(forms.ModelForm):      
    class Meta:
        model = Tutor
        fields = ['want_list']