直接在模型中存储django forms.MultipleChoiceField
假设我有一些选项,定义如下:
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 个回答
我之前也遇到过同样的问题,解决方法对我来说就是,正如Carl Meyer所说的。我不想要一个“字符串列表”的标准化版本,所以在模型里直接用一个CharField就可以了。这样一来,你的模型就能存储这个标准化的项目列表。在我的例子中,这个列表是国家。
所以模型的定义就是
countries = CharField(max_lenght=XXX)
其中XXX是我国家列表的2倍预计算值。这样我们检查当前国家是否在这个列表里就简单多了,而不是用多对多的方式去连接一个国家表。
首先,我建议你考虑更好地规范化你的数据库结构。如果你的模型的一个实例可以有多个这个字段的值,那这个字段可能应该是一个链接的模型,并使用外键来关联。
如果你使用的是Postgres数据库,你还可以使用一个数组字段;Django现在已经有了内置支持。
如果你无法使用上述两种方法,那么你基本上需要重新实现一个(更好的)CommaSeparatedIntegerField。原因是,CommaSeparatedIntegerField其实就是一个普通的字符字段,它的默认表单字段表示是经过正则验证的文本输入。换句话说,它对你并没有什么实质性的帮助。
你需要编写的是一个自定义的ListField或MultipleValuesField,它期待一个Python列表并返回一个Python列表,但在内部将这个列表转换为以逗号分隔的字符串,以便插入到数据库中。可以查看关于自定义模型字段的文档;在你的情况下,你可能需要CharField的一个子类,并重写两个方法:to_python(将CSV字符串转换为Python列表)和get_db_prep_value(将Python列表转换为CSV字符串)。