【问题标题】:Store django forms.MultipleChoiceField in Models directly将 django forms.MultipleChoiceField 直接存储在模型中
【发布时间】:2009-09-09 13:14:55
【问题描述】:

假设我有如下定义的选择:

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 应该做的功能。

【问题讨论】:

    标签: python django django-models django-forms


    【解决方案1】:

    我会考虑的第一件事是更好地规范您的数据库架构;如果您的模型的单个实例可以对此字段有多个值,则该字段可能应该是一个带有 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 字符串)。

    【讨论】:

    • 我认为子类化 TextField 会更合适,因为 CharField 需要 max_length 参数,而 PostgreSQL INT[] 不需要。
    • @danilo 不知道为什么 PostgreSQL INT 在这里是相关的,因为这个想法是将逗号分隔的整数存储在非整数字段中。无论如何,子类化 TextField 也可以。
    • 抱歉,我显然混淆了两个不同的 Stackoverflow 问题。我的意思是 - 如果有人想通过创建自定义字段将列表存储到 Postgres-INT[]-field 中,他应该扩展 TextField :) 但看起来该评论不适合这里。
    【解决方案2】:

    我刚刚遇到了同样的问题和解决方案(对我而言),因为正如 Carl Meyer 所说。我不希望这个“字符串列表”的标准化版本只是在模型中有一个 CharField。这样,您的模型将存储标准化的项目列表。就我而言,这是国家/地区。

    所以模型声明就是

    countries = CharField(max_lenght=XXX) 
    

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

    【讨论】:

    • 我应该指出,从官方 django 文档来看,MultipleChoiceField 将序列化为正确的字符串列表并不明显。
    猜你喜欢
    • 1970-01-01
    • 2012-01-29
    • 1970-01-01
    • 2019-10-22
    • 2010-10-12
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多