直接在模型中存储django forms.MultipleChoiceField

时间:2009-09-09 13:14:55

标签: python django django-models django-forms

说我的选择定义如下:

choices = (('1','a'),
           ('2','b'),
           ('3','c'))

一个在MultipleChoiceField中呈现和输入这些值的表单,

class Form1(forms.Form):
    field = forms.MultipleChoiceField(choices=choices)

在模型中存储field的正确方法是什么。

我当然可以遍历forms.cleaned_data['field']并获取适合models.CommaSeperatedIntegerField的值。

同样,每次我检索这些值时,我都必须循环并转换为选项。

我认为有更好的方法可以这样做,就像这样,我正在重新实现CommaSeperateIntegerField应该执行的功能。

2 个答案:

答案 0 :(得分:10)

我要考虑的第一件事是更好地规范化数据库模式;如果模型的单个实例可以为此字段设置多个值,则该字段可能应该是具有ForeignKey的链接模型。

如果你正在使用Postgres,你也可以使用ARRAY字段; Django现在有built-in support

如果你不能做其中任何一个,那么你基本上需要重新实现一个(更好的)CommaSeparatedIntegerField版本。原因是CommaSeparatedIntegerField只是a plain CharField whose default formfield representation is a regex-validated text input。换句话说,它没有做任何对你有用的事情。

您需要编写的是自定义ListField或MultipleValuesField,它需要Python列表并返回Python列表,但在内部将该列表转换为逗号分隔的字符串,以便插入数据库。阅读documentation on custom model fields;我认为在你的情况下你会想要一个CharField的子类,其中有两个方法被覆盖:to_python(将CSV字符串转换为Python列表)和get_db_prep_value(将Python列表转换为CSV字符串)。

答案 1 :(得分:1)

我有同样的问题和解决方案(对我来说)因为正如卡尔迈耶所说的那样。我不希望这个“字符串列表”的标准化版本只是在模型中有一个CharField。这样,您的模型将存储规范化的项目列表。就我而言,这是国家。

因此模型声明只是

countries = CharField(max_lenght=XXX) 

其中XXX是我的国家/地区列表的2x的预先计算值。因为我们更容易应用检查以查看当前国家/地区是否在此列表中,而不是将其作为M2M到国家/地区表格。