说我的选择定义如下:
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应该执行的功能。
答案 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到国家/地区表格。